下面的代码是从数据库中获取特定数量的引用,从一些DBSCAN函数给出的一些坐标中绘制圆覆盖图,并在Map上绘制圆覆盖图。每隔10秒,圆从Map中删除,并使用数据库中的相同圆进行更新。问题是圆没有显示出来。我已经尝试过调试,但没有用。任何建议/帮助都很感激。
import MapKit
import SwiftUI
import Firebase
import FirebaseAnalytics
import FirebaseAnalyticsSwift
struct ContentView: View {
@StateObject private var viewModel = ContentViewModel()
/* Variable region accounts for showing specific coordinate region within span, showcasing input coordinates */
@State var annotationItems: [User] = []
@State var locations: [CLLocation] = []
@State var circleOverlays: [MKCircle] = []
func plotUsers() {
for i in 0...20
{
var latData = 0.0
var longData = 0.0
var userName = ""
var userAge = 0
var ref: DatabaseReference!
ref = Database.database().reference().child("users").child(String(i))
ref.getData(completion: { error, snapshot in
guard error == nil else {
print("issue")
return;
}
var a: [String: Any] = [:]
//turning datasnapshot returned from database into a dictionary
a = snapshot?.value as! Dictionary<String, Any>
//assigning values from the dictionary to variables so we don't have to type all the necessary error stuff every time
latData = (a["locData"] as? [String:Any])?["lat"] as? Double ?? -1
longData = (a["locData"] as? [String:Any])?["long"] as? Double ?? -1
userName = (a["name"]) as! String
userAge = Int((a["age"] as? [String:Any])?["age"] as? String ?? "-1") ?? -5
annotationItems.append(User(name:userName,age: userAge,latitude: latData,longitude: longData))
self.locations.append(CLLocation(latitude: latData, longitude: longData))
});
}
print("@@@@@@@@@@@@@@@@@@@@@@@Locations:@@@@@@@@@@@@@@@@@@@@@@@@",locations.count)
let dbscan = DBSCAN(self.locations)
let (sequence, places) = dbscan.findCluster(eps: 1000.0, minPts: 2)
print("@@@@@@@@@@@@@@@@@@@@@@@Places:@@@@@@@@@@@@@@@@@@@@@@@@",places)
for place in places {
print("Cluster:", place.members.count)
let circle = MKCircle(center: place.location.coordinate, radius: 10000)
self.circleOverlays.append(circle)
}
self.viewModel.mapView.addOverlays(circleOverlays)
print("@@@@@@@@@@@@@@@@@@@@@@@Circles:@@@@@@@@@@@@@@@@@@@@@@@@",circleOverlays)
}
private var timer: Timer?
var body: some View {
Map(coordinateRegion: $viewModel.region,
showsUserLocation: true)
.onAppear() {
// viewModel.mapView.delegate = viewModel
let _ = self.plotUsers()
// let _ = self.plotUsers()
timer?.invalidate()
Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { _ in
let _ = self.plotUsers()
self.locations.removeAll()
self.viewModel.mapView.removeOverlays(circleOverlays)
self.circleOverlays.removeAll()
}
}
}
}
struct ContentView_Previews: PreviewProvider { /* Shows map */
static var previews: some View {
ContentView()
}
}
final class ContentViewModel: NSObject, ObservableObject, CLLocationManagerDelegate, MKMapViewDelegate {
@Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(
latitude: 38.898022, longitude: -77.050604),
span: MKCoordinateSpan(
latitudeDelta: 0.05, longitudeDelta: 0.05)) /* Can substitute region coordinates with longitude,latitude from firebase */
@Published var map = MKMapView()
var locationManager: CLLocationManager? /* Enables location services*/
let mapView: MKMapView!
override init() {
mapView = MKMapView()
super.init()
mapView.delegate = self
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let circleOverlay = overlay as? MKCircle {
let circleRenderer = MKCircleRenderer(circle: circleOverlay)
circleRenderer.fillColor = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 0.3)
circleRenderer.strokeColor = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 0.7)
circleRenderer.lineWidth = 2.0
return circleRenderer
}
return MKOverlayRenderer()
}
}
我是Swift的新手,所以我不完全确定是否应该以某种方式将$viewModel.region设置为在ContentViewModel类中创建的MKMapView。
1条答案
按热度按时间4ioopgfo1#
这里是
MKMapView
和UIViewRepresentable
,如果你决定走这条路。这将通过将MKCircles
添加到数组中,在用户点击Map的任何地方放置一个圆圈。这不完全是你想要的-我不确定如何合并和测试你的数据库功能-但希望这在某种程度上有助于看到一个选项: