kingpin
kingpin copied to clipboard
How can I subclass the KPAnnotation to add a few properties?
How can I subclass the KPAnnotation to add a few properties? I want to add more some properties to using for a custom annotation view. Thanks!
Hmm, great question. There's no good way to do this right now, which is unfortunate. Off the top of my head, maybe we could add a property like @property (nonatomic) Class clusterAnnotationClass
on KPTreeController so that KPTreeController can instantiate the desired type of cluster annotation class? If you're up for it, it should be an easy addition. Pull requests always welcome :)
Hello, Brian.
As of this commit this is finally possible now.
Please, review my changes. We can close this issue when dev
branch will be merged into master one day.
@stanislaw I am trying to implement this into my project, but having a hard time accessing my properties on the custom class. When you have some time can you build it into the demo?
Here is what I am trying to do.
self.treeController2.configuration.annotationClass = [CustomKPAnnotation class];
...
CustomKPAnnotation *a2 = [[CustomKPAnnotation alloc] init];
a2.coordinate = CLLocationCoordinate2DMake(sfCoord.latitude + latAdj,
sfCoord.longitude + lngAdj);
a2.detailObject = @"DETAIL2";
When I read the detailObject
in viewForAnnotation
it is always nil. I believe it is because the annotation is rebuilt in the controller and the property is lost.
Thanks.
@walsht, you are catching us in the middle of our rework of kingpin's both private internals and public API interface. It is not possible to accomplish the what you're trying right now because of details of current kingpin's design.
You are absolutely right on the following:
I believe it is because the annotation is rebuilt in the controller and the property is lost.
Let's see how kingpin currently works:
We pass an input with our annotations to a tree controller which produces new KPAnnotation-based classes which hold our input annotations stored in their @annotations property. This means that indeed if you set @detailObject
with some data on your input annotations you will lose them later when you'll get an output of grid clustering algorithm and try to access @detailObject
on this new cluster annotations.
How kingpin will work soon (my implementation of this will appear soon in dev
branch):
- KPAnnotation will be renamed to KPClusterAnnotation and will be no more an annotation class for single annotations that you pass tree controller when creating it.
- annotationClass configuration property will be renamed to clusterAnnotationClass.
- clustering algorithm will return KPClusterAnnotation instances for clusters having more than one annotation (truly clusters!) and it will return your original input single annotations if nothing to be clustered in a particular cluster grid. This configuration will make it possible for developers to really customize both their single annotations and the cluster annotations each in its own way, because there will be no interference beetween these two kinds of annotations: single annotations and cluster annotations.
I hope to accomplish this during this week. Meanwhile, I can't give you a good advice on how to accomplish this really well before this design change I've described is done.
Shortly: I ask you to wait until we'll have this new kingpin at least in the kingpin:dev
branch. Sorry for this inconvenience you're facing as a developer.
P.S. I hope I've made my explanation clear with my russian english.
@stanislaw Sounds good to me. Thank you.
Hi!
I've been spending some time digging into the code on the dev
branch and I wanted to quickly follow up on this issue.
KPAnnotation isn't designed to be a place for persisting data. Due to the nature of annotation clustering, anything you display on the map will depend on the contents of the cluster (i.e the number of items, the pin image, etc) and since cluster contents change often, any data you persist will most likely have to be refreshed anyway. Therefore, you are better off dynamically calculating any data on the fly in your annotation view class. I also admit that I might not be seeing the use case for this functionality. @walsht - perhaps you can shed some insight as to how you are trying to use this?
I do agree that returning clusters for single annotations is a bit of a strange pattern, but it makes the underlying clustering/animation code much easier to deal with. I'm open to trying to deal with it cleanly, though it won't prevent you from having to do isKindOfClass checks when returning annotation views, so I'm not sure how much we'd really gain. Anyway, we should probably open a separate issue for this.
@itsbonczek
In my app, I am using Core Data to determine what pins are on the map. Each pin has a different pin image and tapping on it I display the detail. So, I set a object (in my case a NSManagedObject
) on the annotation and read it on the viewForAnnotation
and didSelectAnnotationView
, without more work to get the detail.
I could have put a identifier into the annotation's title or use the lat/lon, but it is just more work when I already have the object.
As for the cluster pin, I am ok with it being one annotation. Since, I check if it is a cluster and have a specific image in viewForAnnotation
and just zoom in when didSelectAnnotationView
is run for a clustered annotation.
Maybe a better solution would be to have a NSArray
of objects on the KPAnnotation
. Then the user can read the one or multiple objects and do custom processing.
Let me know if you need more clarification. Thank you.