#ios #xcode #map #mapbox #markerclusterer
#iOS #xcode #словарь #mapbox #markerclusterer
Вопрос:
Я использую Mapbox sdk в своем проекте. https://www.mapbox.com/mapbox-ios-sdk /
У меня работает базовая кластеризация, но мой вопрос в том, как мне дальше растворять кластер по щелчку мыши.
например. У меня есть кластер с 8 маркерами. По щелчку он должен увеличивать масштаб не только на один уровень, но и до точки, где все 8 маркеров отображаются на экране с максимально возможным увеличением.(некоторые маркеры из этих 8 могут быть сгруппированы)
Я попробовал [масштабирование карты с широтой и длиной юго-запада: CLLocationCoordinate2DMake (юг, запад) Северо-восток: CLLocationCoordinate2DMake (север, восток) анимированный: ДА]; но безуспешно.
Ответ №1:
Вот как это получилось:
- (void)tapOnAnnotation:(RMAnnotation *)annotation onMap:(RMMapView *)map {
if (annotation.isClusterAnnotation) {
CLLocationCoordinate2D southwestCoordinate = annotation.coordinate;
CLLocationCoordinate2D northeastCoordinate = annotation.coordinate;
for (RMAnnotation *plot in annotation.clusteredAnnotations) {
CGFloat latititude = plot.coordinate.latitude;
CGFloat longitude = plot.coordinate.longitude;
if (southwestCoordinate.latitude > fabsf(latititude)) southwestCoordinate.latitude = latititude;
if (southwestCoordinate.longitude > fabsf(longitude)) southwestCoordinate.longitude = longitude;
if (northeastCoordinate.latitude < fabsf(latititude)) northeastCoordinate.latitude = latititude;
if (northeastCoordinate.longitude < fabsf(longitude)) northeastCoordinate.longitude = longitude;
}
[self.mapView zoomWithLatitudeLongitudeBoundsSouthWest:southwestCoordinate northEast:northeastCoordinate animated:YES];
}
}
По сути, здесь происходит то, что я сохраняю ограничивающие координаты самой удаленной области southwestCoordinate
и northeastCoordinate
аннотацию к ней (в данном случае, кластер). Затем для каждой аннотации внутри кластера мы проверяем, является ли абсолютное расстояние от этой «центральной» координаты наибольшим в группе.
Кажется, для меня это работает довольно хорошо.
Комментарии:
1. Я начал с аналогичного подхода, но я считаю, что мой ответ является улучшением по сравнению с этим.
Ответ №2:
Следующий фрагмент будет лучше масштабировать точки вашего кластера, расширяясь до уровня, на котором некоторые или все точки не кластеризованы:
// 1. Start with a maximum (world-wide) bounding box
CLLocationCoordinate2D topRight = CLLocationCoordinate2DMake(180, -90);
CLLocationCoordinate2D bottomLeft = CLLocationCoordinate2DMake(-180, 90);
// 2. Derive the minimum bounding box coordinates that contains all cluster points, by "squeezing in" on their coordinates
for (RMAnnotation *a in annotation.clusteredAnnotations) {
if (a.coordinate.latitude < topRight.latitude) {
topRight.latitude = a.coordinate.latitude;
}
if (a.coordinate.longitude > topRight.longitude) {
topRight.longitude = a.coordinate.longitude;
}
if (a.coordinate.latitude > bottomLeft.latitude) {
bottomLeft.latitude = a.coordinate.latitude;
}
if (a.coordinate.longitude < bottomLeft.longitude) {
bottomLeft.longitude = a.coordinate.longitude;
}
}
CLLocation *sw = [[CLLocation alloc] initWithLatitude:topRight.latitude longitude:topRight.longitude];
CLLocation *ne = [[CLLocation alloc] initWithLatitude:bottomLeft.latitude longitude:bottomLeft.longitude];
// 3. Calculate the distance in meters across the calculated bounding box
CLLocationDistance distanceInMeters = [ne distanceFromLocation:sw];
// 4. Adjust the map view's meters per pixel setting so that the bounding box fits nicely within the map views bounds (which is equivalent to zooming)
[self.mapView setMetersPerPixel:(distanceInMeters / (self.mapView.frame.size.width * 0.7)) animated:YES];
// 5. Center on the midpoint of the bounding box
[self.mapView setCenterCoordinate:[self midPointBetween:topRight and:bottomLeft] animated:YES];
Ответ №3:
GoogleMaps
Используется: https://github.com/googlemaps/google-maps-ios-utils для кластеризации
«Кластер без кластера»: D
Swift 3
if let cluster = marker.userData as? GMUCluster {
let boxConstant = 0.01
var southwestCoordinate = cluster.position
var northeastCoordinate = cluster.position
for clusterItem in cluster.items {
let latitude = clusterItem.position.latitude
let longitude = clusterItem.position.longitude
if southwestCoordinate.latitude > latitude {
southwestCoordinate.latitude = latitude
}
if southwestCoordinate.longitude > longitude {
southwestCoordinate.longitude = longitude
}
if northeastCoordinate.latitude < latitude {
northeastCoordinate.latitude = latitude
}
if northeastCoordinate.longitude < longitude {
northeastCoordinate.longitude = longitude
}
}
// Create Box
southwestCoordinate.longitude = boxConstant
southwestCoordinate.latitude -= boxConstant
northeastCoordinate.longitude -= boxConstant
northeastCoordinate.latitude = boxConstant
let bounds = GMSCoordinateBounds(coordinate: southwestCoordinate, coordinate: northeastCoordinate)
self.mapView.moveCamera(GMSCameraUpdate.fit(bounds))
}
Ответ №4:
я бы добавил это в качестве комментария к метатеорическому ответу, но у меня недостаточно репутации.
Я думаю, что с этим fasbf он плохо вычисляет отрицательные координаты и работает лучше без него. Я прав?
- (void)tapOnAnnotation:(RMAnnotation *)annotation onMap:(RMMapView *)map {
if (annotation.isClusterAnnotation) {
CLLocationCoordinate2D southwestCoordinate = annotation.coordinate;
CLLocationCoordinate2D northeastCoordinate = annotation.coordinate;
for (RMAnnotation *plot in annotation.clusteredAnnotations) {
CGFloat latitude = plot.coordinate.latitude;
CGFloat longitude = plot.coordinate.longitude;
if (southwestCoordinate.latitude > latitude) southwestCoordinate.latitude = latitude;
if (southwestCoordinate.longitude > longitude) southwestCoordinate.longitude = longitude;
if (northeastCoordinate.latitude < latitude) northeastCoordinate.latitude = latitude;
if (northeastCoordinate.longitude < longitude) northeastCoordinate.longitude = longitude;
}
[map zoomWithLatitudeLongitudeBoundsSouthWest:southwestCoordinate northEast:northeastCoordinate animated:YES];
}
}