ashare80 / tsclustermapview Goto Github PK
View Code? Open in Web Editor NEWThis project forked from applidium/adclustermapview
MKMapView with animated clustering for iOS and OSX
License: MIT License
This project forked from applidium/adclustermapview
MKMapView with animated clustering for iOS and OSX
License: MIT License
Also tried a needsRefresh call after I added all the annotations, but only way to show them is to resize map. What I'm doing wrong
I have noticed a crash that happens rarely.
The crash happens in the alloc init of the ADClusterAnnotation, in the initAnnotationPools.
appname(46839,0x10a642310) malloc: *** error for object 0x7ffa01ae89b8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Hello, I started playing with this library last Friday and is awesome! But while running some tests I found some things.
I found a small issue when I have 2 annotations in the exactly same point, please see the following screenshot. Is there any way to add more displacement to the annotations when they are "de-clustered"?
https://www.dropbox.com/s/j9ma2i6x9b9i92b/overlapping.png?dl=0
Another issue is when I have some annotations in the same point, when clustering them, the position of the point changes in the map. (see next screenshots)
https://www.dropbox.com/s/7oy7cwex88cgba2/multiple1.png?dl=0
https://www.dropbox.com/s/po5qiw322lc1p09/multiple2.png?dl=0
https://www.dropbox.com/s/xpwewka1xff9a5d/multiple3.png?dl=0
I don't know if this second one might be related to #8
Thanks!
Well, it's not a true 3D "flyover" view, it's about changing the camera view angle with two-fingers up&down "scrolling". Clusterization seems to be always broken after setting the lowest view angle (in any cases). It's never broken with other view angles.
Here's the demo project screenshot:
iPhone 6S, iOS 10.3.2
Hi @ashare80,
I used "self.centerOffset = CGPointMake(0,0);" for a different annotation image in "ClusteredAnnotationView", but animation problems occurred when playing with the map.
Modifying "TSClusterAnnotationView" with code below solved the problem.
FYI
// if (!CGPointEqualToPoint(self.centerOffset, annotationView.centerOffset)) {
// self.centerOffset = annotationView.centerOffset;
// }
self.centerOffset = annotationView.centerOffset;
I cannot select the annotations on the map. But the user location annotation works. Can you please give me a hint.
Cluster annotations and normal annotations are not visible if one removes all annotations and than adds them back again to the MapView.
You can reproduce this behaviour using the TSCClusterMapViewDemo app
Step 1: press +All to add all public bathrooms. The cluster annotation will appear
Step 2: press -All to remove all annotations.
Step 3: press +All again. No cluster annotation will be visible. You have to scroll or zoom the map to force the annotations to appear
Hello, I have a "layout changing" map view (changes the height of the view with some user interactions) and those changes (changing map center coordinates as well) make the annotations going crazy, changing their positions and some disappearing!
Screenshots:
https://www.dropbox.com/s/t3kmqytjzl6wtx9/crazy1.png?dl=0
When I select the annotation in the first "O" of London I change the height of the map and on didSelectAnnotationView: delegation method I do [self.theMap setCenterCoordinate:theannotation.coordinate animated:YES];
That's what I have:
https://www.dropbox.com/s/hdi2n9nwb848974/crazy2.png?dl=0
As you can see, the annotation has been displaced and any other annotations are gone!
The app crahes when trying to add an annotation on a mapView from which a number of annotations has been just removed.
The issue can be reproduced launching the ClusterDemo on an iOS7 device on simulator: add all annotations via "+All" and remove them via "-All". If "+All" is pressed again, it crashes at:
ADClusterAnnotation.m (row 58)
Hi @ashare80,
I noticed another issue and I will provide some screenshots from your sample app tomorrow.
The clustered annotations are moving left when zooming in (displaying regular annotations) and zooming out. If you do it several times you can see the clustered annotations' position are moving left and a little bit down.
Thanks
Cahit
What do you think about porting this library to tvOS? It would be awesome!
[!] Invalid `Podfile` file: [!] Unsupported options `{:exclusive=>true}` for target `TSClusterMapView`..
Playing around with the new code, I realised that sometimes a cluster annotation is suddenly becoming a single annotation and, actually, when you click on that, the map drives you to the location of the single annotation is displaying rather than "opening" the cluster.
I don't know how to reproduce it but is not the first time that happens to me with this new version. Is while using the map zooming in, out, selecting...
Hello, I opened this issue about a feature I would love to have! An app that shows venues that host concerts on map could show a cluster of 4 venue pins but instead of showing the number 4 on it, it could show the sum of concerts of the 4 venues. With the current functionality, I assume I can just remove the annotations that have no concerts. It would be great if we could give a number as metadata on each annotation (number of concerts) and then be able to select to show the sum of this metadata on the clusters. Let me know if this is possible with the current code somehow.
Thanks for all the work!
Hello, after the update, I realised that annotations inside cluster are exchanging location. I attach some screenshots. The price I show is assigned as a property in the annotation (my annotation is a MKPlacemark subclass and that info is inside the AddressDictionary property).
LINKS TO THE SCREENSHOTS:
I have added new viewcontroller with TSClusterMapview.
When I will open this viewcontroller at first, it's working as well. But If I will reopen viewcontroller again (without turn off app), any cluster is not showing.
I have tested it in example project also. It's same issue. If you will add new viewcontroller with TSClusterMapview and show via storyboard or code(self.navigationController pushviewcontroller: YES). You can see issue as well.
How can I fix this issue? Please help me.
Thanks.
I have a couple of annotations which should be clustered always together and not with other annotations. For instance I have an application which shows annotations for certain regions of a city. It would be great if all the annotations in "Manhattan" would join together and the annotations of "Brooklyn" go into a new cluster. Therefor something like a "group ID" could be set while creating the annotations. Is something like this possible or would it change too much the way the cluster algorithm works?
Hello @ashare80,
I noticed a small bug. When you tap on a cluster, the map is zooming on this cluster, then dividing it into several pins/sub-clusters. But when a cluster is englobing pins that are too close, tapping on this cluster is not zooming anymore/at all and is not dividing into pins. I have to manually zoom by hand to see the cluster dividing into pins.
You can test that bug on your demo app. I made a video to show you. Look at the "10" cluster bubble in the center of the screen, when tapping on it, it zooms and I see a "7" cluster bubble appears. But then, when I tap on this "7" cluster bubble, it stays at the same zoom level like it was the maximum zoom level and so I cannot see the pins contained by this "7" cluster bubble.
The video is here: http://fr.tinypic.com/r/2dhs8y0/8
Could you take a look at this problem?
Thanks.
Hi,
I would like to select a clustered annotation programmatically to simulate the user pressing the annotation pin, in order for the map to zoom in to show the annotation's children.
I have tried calling selectAnnotation on the annotation I want to simulate the action in the didFinishBuildingClusterTreeForMapPoints method, with no luck so far. So, what I do is:
id annotation = [mapView.visibleClusterAnnotations objectAtIndex:0];
[(TSClusterMapView *)mapView selectAnnotation:annotation animated:YES];
Nothing happens when doing this. I tried executing this code with a delay too.
Anyone knows how I would go about doing this? It seemed pretty simple at first.
Any help is appreciated. Cheers!
when i open tsclustermapview and touch on cluster to expand, the cpu usage is 200% whose crash the app . i use tsclustermapview version 2.3.1 .
When i open the map view the app crash.
i try to check where is the crash, the map view crash before viewDidLoad.
The trace of the error is this:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
i check in crashlytics to view where is the error and the report is in this file:
TSClusterMapView.m line 36
-[TSClusterMapView initWithCoder:]
There is the code where i put the annotations:
self.annotations = [PoiAnnotation]()
for i in 0 ..< self.pois.count {
if let poi = self.pois.objectAtIndex(i) as? Pois {
let marker = Marker.init(
title: poi.title, subtitle: String(poi.poi_type_id), latitude: (poi.lat as NSString).doubleValue, longitude: (poi.lng as NSString).doubleValue, poi:poi
)
annotations.append(marker.annotation)
}
}
if let annotationFilter = self.defaults.objectForKey("annotationFilter") as? [Int] {
print(annotationFilter)
self.filterCategoriesbyExistentFilter(annotationFilter)
}
self.mapView.addClusteredAnnotations(annotations)
This is only occurred in one device Iphone 5s.
I'm using version 2.10 of the pod.
In my app I've seen instances where cluster annotations vanish incorrectly. I think it most often happens when moving some annotations off-screen, zooming in the map somewhat, then moving to make those annotations on-screen again. The correct annotations are present while panning the map, but sometimes disappear after the drag stops.
I tried debugging TSClusterOperation
, but it made my head hurt.
I think I've found a work-around that seems make the annotations re-appear immediately after they've vanished. In mapView:regionDidChangeAnimated: I added:
// make extra call to layout clusters shortly after panning stops
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(RefreshClustersAfterPanDelay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.mapView needsRefresh];
});
I found it difficult to reproduce with a small number of annotations, somewhat easier when there's hundreds. I could potentially provide an app and a data set that might help.
@ashare80 When I was testing the latest version I see cluster annotations with no text several times. They were at close zoom levels. Did you see anything like that?
I could not recreate it, I will let you know if find out how to do it.
Thanks
https://www.youtube.com/watch?v=Ud-d4giz_4A
You can see the video, these are 2 red and 1 green annotation I want to show you.
when I drag them to off the screen, and drag them back, they may disappear or swap the other annotation. it happens very often.
My DB has about few hundred annotation. Is my implementation problem or the library bug?
` func removeAllPin(){
mapView_.removeAnnotations(pin_mcs_)
mapView_.removeAnnotations(pin_mcp_)
mapView_.removeAnnotations(pin_pcs_)
mapView_.removeAnnotations(pin_pcp_)
mapView_.removeAnnotations(pin_petrol_)
mapView_.removeAnnotations(pin_speedingCamera_)
pin_mcs_.removeAll()
pin_mcp_.removeAll()
pin_pcs_.removeAll()
pin_pcp_.removeAll()
pin_petrol_.removeAll()
pin_speedingCamera_.removeAll()
}
func addAllPin(){
var tempArray:[MKAnnotation] = []
if(toggle_pin_mcs_.selected){
tempArray += pin_mcs_ as [MKAnnotation]
}
if(toggle_pin_mcp_.selected){
tempArray += pin_mcp_ as [MKAnnotation]
}
if(toggle_pin_pcs_.selected){
tempArray += pin_pcs_ as [MKAnnotation]
}
if(toggle_pin_pcp_.selected){
tempArray += pin_pcp_ as [MKAnnotation]
}
if(toggle_pin_petrol_.selected){
tempArray += pin_petrol_ as [MKAnnotation]
}
if(toggle_pin_speedingCamera_.selected){
tempArray += pin_speedingCamera_ as [MKAnnotation]
}
mapView_.addClusteredAnnotations(tempArray)
}
func mapView(mapView: TSClusterMapView!, viewForClusterAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
var view:MyClusterAnnotationView? = self.mapView_.dequeueReusableAnnotationViewWithIdentifier(NSStringFromClass(MyClusterAnnotationView.self).componentsSeparatedByString(".").last!) as? MyClusterAnnotationView
if(view == nil){
view = MyClusterAnnotationView(annotation: annotation, reuseIdentifier: NSStringFromClass(MyClusterAnnotationView.self).componentsSeparatedByString(".").last!)
}
return view;
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
var view:MKAnnotationView?
if (annotation is PinMcsAnnotation) {
view = self.mapView_.dequeueReusableAnnotationViewWithIdentifier(NSStringFromClass(PinMcsAnnotation.self).componentsSeparatedByString(".").last!)
if(view == nil){
view = MKAnnotationView(annotation: annotation, reuseIdentifier: NSStringFromClass(PinMcsAnnotation.self).componentsSeparatedByString(".").last!)
}
view!.image = UIImage(named: "map_pin_mcs")
view?.canShowCallout = false
view?.centerOffset = CGPointMake(view!.centerOffset.x, -view!.frame.size.height/2)
}
else if (annotation is PinMcpAnnotation) {
view = self.mapView_.dequeueReusableAnnotationViewWithIdentifier(NSStringFromClass(PinMcpAnnotation.self).componentsSeparatedByString(".").last!)
if(view == nil){
view = MKAnnotationView(annotation: annotation, reuseIdentifier: NSStringFromClass(PinMcpAnnotation.self).componentsSeparatedByString(".").last!)
}
view!.image = UIImage(named: "map_pin_mcp")
view?.canShowCallout = false
view?.centerOffset = CGPointMake(view!.centerOffset.x, -view!.frame.size.height/2)
}
else if (annotation is PinPcsAnnotation) {
view = self.mapView_.dequeueReusableAnnotationViewWithIdentifier(NSStringFromClass(PinPcsAnnotation.self).componentsSeparatedByString(".").last!)
if(view == nil){
view = MKAnnotationView(annotation: annotation, reuseIdentifier: NSStringFromClass(PinPcsAnnotation.self).componentsSeparatedByString(".").last!)
}
view!.image = UIImage(named: "map_pin_pcs")
view?.canShowCallout = false
view?.centerOffset = CGPointMake(view!.centerOffset.x, -view!.frame.size.height/2)
}
else if (annotation is PinPcpAnnotation) {
view = self.mapView_.dequeueReusableAnnotationViewWithIdentifier(NSStringFromClass(PinPcpAnnotation.self).componentsSeparatedByString(".").last!)
if(view == nil){
view = MKAnnotationView(annotation: annotation, reuseIdentifier: NSStringFromClass(PinPcpAnnotation.self).componentsSeparatedByString(".").last!)
}
view!.image = UIImage(named: "map_pin_pcp")
view?.canShowCallout = false
view?.centerOffset = CGPointMake(view!.centerOffset.x, -view!.frame.size.height/2)
}
else if (annotation is PinPetrolAnnotation) {
view = self.mapView_.dequeueReusableAnnotationViewWithIdentifier(NSStringFromClass(PinPetrolAnnotation.self).componentsSeparatedByString(".").last!)
if(view == nil){
view = MKAnnotationView(annotation: annotation, reuseIdentifier: NSStringFromClass(PinPetrolAnnotation.self).componentsSeparatedByString(".").last!)
}
view!.image = UIImage(named: "map_pin_petrol")
view?.canShowCallout = false
view?.centerOffset = CGPointMake(view!.centerOffset.x, -view!.frame.size.height/2)
}
else if (annotation is PinSpeedingCameraAnnotation) {
view = self.mapView_.dequeueReusableAnnotationViewWithIdentifier(NSStringFromClass(PinSpeedingCameraAnnotation.self).componentsSeparatedByString(".").last!)
if(view == nil){
view = MKAnnotationView(annotation: annotation, reuseIdentifier: NSStringFromClass(PinSpeedingCameraAnnotation.self).componentsSeparatedByString(".").last!)
}
view!.image = UIImage(named: "map_pin_speeding_camera")
view?.canShowCallout = false
view?.centerOffset = CGPointMake(view!.centerOffset.x, -view!.frame.size.height/2)
}
return view;
}
func mapView(mapView: TSClusterMapView!, shouldForceSplitClusterAnnotation clusterAnnotation: ADClusterAnnotation!) -> Bool {
return true
}
func mapView(mapView: TSClusterMapView!, shouldRepositionAnnotations annotations: [ADClusterAnnotation]!, toAvoidClashAtCoordinate coordinate: CLLocationCoordinate2D) -> Bool {
return true
}
`
Hii,
First, thank you for sharing this great and useful lib.
I am trying to use it, but I want a little different behavior when I give zoom in the last level and is not be possible to ungroup the pins. In this scenario, I want to intercept the default behavior (replace the pins around the original coordinate when the user tap on pin). In my case I wish to display some list with the places data (because I need to show all shops (200+) in the mall, for example). But I was not be able to disable this default behavior and insert my code.
If there is a way, I appreciate it if you could help me.
Thank you very much!
Best regards,
Paulo Santana.
I tested all and everything well in debug build, but when I upload to app store, try on test flight.
It is nothing to show on the map.
version 2.3.1
Crash Report:
Inside "TSClusterMapView.m":
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
....
if (MKMapRectSizeIsGreaterThanOrEqual(zoomTo, self.visibleMapRect)) {
zoomTo = MKMapRectInset(zoomTo, zoomTo.size.width/4, zoomTo.size.width/4);
//At this point zoomTo.size.height becomes negative
}
MKCoordinateRegion region = MKCoordinateRegionForMapRect(zoomTo);
//and negative zoomTo results in negative(invalid) region.span.latitudeDelta
....
[self setRegion:region animated:YES];
//Which results in a crash in this line with the invalid region being set
}
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid Region <center:+40.97086950, +29.03882550 span:-0.00556946, +0.01978016>' ***
Scenario:
Q:What makes (MKMapRectSizeIsGreaterThanOrEqual(zoomTo, self.visibleMapRect))
equal to YES
?
A:In my particular case for some clusters(not leafs), when I touch on them the map starts zooming towards the center of the clusterAnnotationView
which is good and expected. But for some reason, animation stops early and does not split the cluster that is selected. When the setRegion animation stops, I touch on the same cluster again and MKMapRectSizeIsGreaterThanOrEqual
returns yes and I get the crash.
Conclusion:
I can fork the project and make sure the region values are valid before fed into setRegion:Animated: but this is not the real issue. I want to know why the cluster does not get broken when touched on it and stops early and how to avoid this.
In one mode of my mapview, its setup with a single draggable annotation with a custom view. After the drag starts and the annotation view has moved a few pixels (like 5-10), something is causing the mapview to set its drag state to MKAnnotationViewDragStateEnding
. Also, the touch that was dragging the annotation starts scrolling the map instead. I change my mapview from a TSClusterMapView
subclass to a plain MKMapView
and this no longer happens.
The stack trace at the time seems only shows execution of the mapview's gesture recognizers. It looks like at this point the touch has already been taken over by the pan gesture recognizer for scrolling, and that this itself is causing the drag to end.
* frame #0: 0x000000010750b6f6 Wundrit`-[PendingQuestionAnnotationView setDragState:animated:](self=0x00007ffcb9950620, _cmd=0x0000000116f54852, newDragState=MKAnnotationViewDragStateEnding, animated=false) + 342 at MainMapViewController.m:1485
frame #1: 0x000000010a60cb81 MapKit`-[MKAnnotationContainerView _dropDraggingAnnotationViewAnimated:] + 280
frame #2: 0x000000010a55cb95 MapKit`-[MKMapView _dropDraggingAnnotationView:] + 90
frame #3: 0x000000010a55e10a MapKit`-[MKMapView _willChangeRegionAnimated:] + 87
frame #4: 0x00000001169c2b29 VectorKit`-[VKMapCameraController startPanningAtPoint:panAtStartPoint:] + 89
frame #5: 0x000000010a59ac21 MapKit`-[MKMapGestureController handlePan:] + 384
frame #6: 0x000000010ab4c656 UIKit`_UIGestureRecognizerSendActions + 262
frame #7: 0x000000010ab4b2f9 UIKit`-[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 532
So what could be causing the scrolling recognizer to be taking over the touch that started out belonging to the annotation drag?
I was thinking the UIPanGestureRecognizer
that's setup in initHelpers
was somehow to blame (what is the point of that anyway?), but I commented out the creation of that recognizer and the problem is still happening.
Any ideas for what this could be or how to debug this?
A little detail to the behaviour of leaf annotations turning to clustered annotations while zooming out of the map:
It would be great if the leaf annotations would stay as they are but move to the mutual position and afterwards turn into the clustered annotation. Right now the annotations are already changed to clustered annotations (including number and UIImage) and then they are moved to the mutual position and all except one get deleted.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.