'1000 Clickable markers': Use 'MapUtils.createTappableMarker(..' as in example or is there a better method?

300 views
Skip to first unread message

Martin Vennekamp

unread,
Dec 2, 2014, 7:00:23 PM12/2/14
to mapsfo...@googlegroups.com

Hi, first of all many thanks for the great work on this library. I'm about to use it for a hiking map, which should also deliver additional information on some landmarks.(i.e. some summits, which can be found in the openstreetmap source I'm using) In my current application, the maps displays the summits as icon, as defined in the rendertheme. Everything works fine ;-)

 

I like to make the representation of these summit (i.e. the icons, as shown on the map) 'clickable', but I'm wondering how to achieve that? 

Of course, one could create many TappableMarkers, but:

  • how well scales this method for some thousand items? And, 
  • are there some helper-methods which make the markers appear/disappear depending on their population on the map?
  •  Or, is there a completely different approach?

I’m using the SVG-rendertheme and I think about the nice way to attach a ‘onClick’ listener to an SVG element on a HTML page. ;-)

 

Thanks in Advance for any answer & best regards,

 

Martin

 

 

Emux

unread,
Dec 3, 2014, 2:36:37 AM12/3/14
to mapsfo...@googlegroups.com
That's an interesting issue that can happen one way or another in a lot of of us.

- I have tried with hundreds of markers and admittedly it hurts performance.
Even while the library is already clever enough to draw only the markers inside the map window.

- I think that's called marker clustering, no there is no such method yet.
Though it's in my plans to play with it unless somebody else has already a patch. :-)

- A method to try is to place the markers inside the map file (you have to create a new custom map).
Then also build an small offline sqlite / spatialite with the marker properties and coordinates (point or bounding box).
From the tap lat,long you can query the db and retrieve the marker info.

--
Emux
Cruiser - Atlas

Ludwig

unread,
Dec 3, 2014, 4:10:02 AM12/3/14
to mapsfo...@googlegroups.com
I would be in favour of producing something within the Samples app that shows such an application. 

Ludwig

--
You received this message because you are subscribed to the Google Groups "mapsforge-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mapsforge-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mapsforge-dev/547EBD95.80503%40gmail.com.

For more options, visit https://groups.google.com/d/optout.

Martin Vennekamp

unread,
Dec 7, 2014, 8:30:01 PM12/7/14
to mapsfo...@googlegroups.com
I almost finished an example with approx. 200 hotels in Berlin, would you be interessted in the files?

Regards,

Martin

Ludwig

unread,
Dec 8, 2014, 10:26:45 AM12/8/14
to mapsfo...@googlegroups.com
Yes, as long as the data is suitable for use in mapsforge (some sort of liberal data license), otherwise we can substitute some dummy data.

As I said, best would be an example for the Samples app.

Ludwig

--
You received this message because you are subscribed to the Google Groups "mapsforge-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mapsforge-de...@googlegroups.com.

Martin Vennekamp

unread,
Dec 8, 2014, 4:47:51 PM12/8/14
to mapsfo...@googlegroups.com

Am Montag, 8. Dezember 2014 16:26:45 UTC+1 schrieb Ludwig:
As I said, best would be an example for the Samples app.

Ludwig
 


So, here are my files, I extended the 'DummyContent' Class to create more 'DummyItems', which are queried from from http://nominatim.openstreetmap.org.

This is inspired by https://code.google.com/p/osmbonuspack/wiki/Tutorial_2

     i.e.  https://code.google.com/p/osmbonuspack/source/browse/trunk/OSMBonusPack/src/org/osmdroid/bonuspack/location/NominatimPOIProvider.java

but I use a XML Parser, thus I needed to add an additional XML parser class. 

The item list is posted to the BubbleOverlay and represented as marker there. I think it should work without problem.


The next step would be to cluster the items, I have looked through the internet and found some advice on doing that:

https://arnaldog.wordpress.com/2013/07/31/simple-clustering-with-android-maps-v2/ (I hadn't much time to look into that, but seems to be pretty straightforward..) 

http://stackoverflow.com/questions/10410217/cluster-marker-openstreetmap-java (see the link in the answer there)

http://code.google.com/p/osmbonuspack/wiki/Tutorial_3  (also includes sample code)


I hope I can get deeper into that later...


Regards, Martin


P.S.: Any comment on this or the creation of clustering-class?
BubbleOverlay.java
ManyDummyContent.java
StackOverflowXmlParser.java

Ludwig

unread,
Dec 8, 2014, 4:50:25 PM12/8/14
to mapsfo...@googlegroups.com
Thanks, I will look into that, probably on Wednesday.

Ludwig

--
You received this message because you are subscribed to the Google Groups "mapsforge-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mapsforge-de...@googlegroups.com.

Emux

unread,
Dec 9, 2014, 4:57:03 AM12/9/14
to mapsfo...@googlegroups.com
Thanks for the info Martin.

Off topic: if I may suggest to better use json instead of xml for the web services.
Android has build in support and there is always the excellent Gson library.

Martin Vennekamp

unread,
Dec 17, 2014, 1:51:32 PM12/17/14
to mapsfo...@googlegroups.com
In the last days I have created a working example for marker clustering: https://github.com/vennekamp/mapsforge 

Nevertheless, still have a problem with a onTap-Event. I'm using a class to display the marker:
package org.mapsforge.applications.android.samples.markerclusterer; .... public class ClusterMarker extends Layer {

If I implement an onTap-Listener:
public boolean onTap(LatLong geoPoint, Point viewPosition, Point tapPoint) {
..it is called, but the viewPosition is always null.

Any help for that issue?

Martin

Emux

unread,
Dec 17, 2014, 2:16:06 PM12/17/14
to mapsfo...@googlegroups.com
Hi Martin,

The 2nd argument 'layerXY' is the result of conversion from geographic coordinates to pixels.
Checking the code I see we can have cases that it can be null.
If the layer has not geographic position or the map view has not layout.

We would need more information for helping.
Why not extending Marker class instead?

By the way, the screenshots in the fork seem quite interesting.
What algorithm are you trying, grid / radius clustering?

Ludwig

unread,
Dec 17, 2014, 2:42:33 PM12/17/14
to mapsfo...@googlegroups.com
To add to what Emux just said there are two kinds of layers:
  1. A layer like a tile layer that has no geographic position (it spans the whole map view). So a on tap will only give you where you clicked on the layer.
  2. A layer like a marker that has a position (like a marker), they have to override getPosition() to return the lat/long they are associated with. 
I see that you have already something like this in Cluster, but maybe that is something that does not work correctly.

Ludwig


--
You received this message because you are subscribed to the Google Groups "mapsforge-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mapsforge-de...@googlegroups.com.

Martin Vennekamp

unread,
Dec 17, 2014, 3:32:10 PM12/17/14
to mapsfo...@googlegroups.com

Thanks for the quick answers, & now I got it: simply overriding "getPosition" solved the problem. So, why is it not abstract in the layer class?

 

Shortly answer your questions:

- I have not extending 'Marker', because it's variables are 'private' - could they be 'protected'? Additionally, I'm defining the Clustermarker without knowing it's position, bitmap aso. Thus, I would like to have an empty super constructor.

- The algorithm is not very elaborated: It is a grid-based algorithm, but the grid is placed around it's first element. From a not clustered element a Cluster is created and all elements closer in X- or Y-axis to this first element are added to the cluster.

 

Best Regards, Martin

 

Ludwig

unread,
Dec 17, 2014, 3:34:37 PM12/17/14
to mapsfo...@googlegroups.com

Thanks for the quick answers, & now I got it: simply overriding "getPosition" solved the problem. So, why is it not abstract in the layer class?

 
Could possibly be, not everything is perfect. 
 

 

Shortly answer your questions:

- I have not extending 'Marker', because it's variables are 'private' - could they be 'protected'? Additionally, I'm defining the Clustermarker without knowing it's position, bitmap aso. Thus, I would like to have an empty super constructor.

 
Again, if there is a good reason for the variables to be protected I am happy to change that.

Ludwig

Martin Vennekamp

unread,
Dec 17, 2014, 3:52:18 PM12/17/14
to mapsfo...@googlegroups.com
Am Mittwoch, 17. Dezember 2014 21:34:37 UTC+1 schrieb Ludwig:

Could possibly be, not everything is perfect. 


Of course not, especially in my code - & I just tried an 'abstarct' and it did not work ;-)

Martin


Emux

unread,
Dec 17, 2014, 3:58:12 PM12/17/14
to
On 17/12/2014 10:32 μμ, Martin Vennekamp wrote:

Thanks for the quick answers, & now I got it: simply overriding "getPosition" solved the problem. So, why is it not abstract in the layer class?


As noted by Ludwig, the Layer is extended by classes that don't need to return a position, i.e. TileLayer.

 

- I have not extending 'Marker', because it's variables are 'private' - could they be 'protected'? Additionally, I'm defining the Clustermarker without knowing it's position, bitmap aso. Thus, I would like to have an empty super constructor.


The constructor parameters can be null and be changed later many times via the set methods.
Reply all
Reply to author
Forward
0 new messages