I am using Mapsforge 0.5 for android. I have added some markers to the map with:
map.getLayerManager().getLayers().add(layer);
What I am trying to do is change the position of an existing layer. I have a reference to the object stored, but there isn't any way to move the marker. There is only a getter for the position
layer.getPosition() : LatLong
The latitude and longitude fields of LatLong are final :( I have solved the problem by first removing the layer and then adding it again but that results in some additional coordination logic. Is there some way I can actually move a Layer (Marker)?
Mapsforge treats layers to be anything like render layer, tile layer, map overlays like markers, etc.
The abstract class Layer defines the getPosition() method to return null, by default.
Some classes extended from it like TileLayer does not modify the method's behavior. But, some Layer's extended classes do modify it.
In your case, a map overlay type, the Marker class extends from Layer with a modified getPosition() method. The value of the private field Marker.this.latLong is not even final. It accepts a change to Marker.this.latLong via Marker.setLatLong() method.
Provided that the Layer object is really an instance of Marker, you can cast the object as Marker.
Related
Here is mapBox sample to draw a line geometry.
private void onStyleLoaded(Style style) {
initRouteCoordinates();
style.addSource(new GeoJsonSource("line-source",
FeatureCollection.fromFeatures(new Feature[]{
Feature.fromGeometry(LineString.fromLngLats(routeCoordinates))})));
style.addLayer(new LineLayer("lineLayer", "line-source")
.withProperties(PropertyFactory.lineDasharray(new Float[] {0.01f, 2f}),
PropertyFactory.lineCap(Property.LINE_CAP_ROUND),
PropertyFactory.lineJoin(Property.LINE_JOIN_ROUND),
PropertyFactory.lineWidth(5f),
PropertyFactory.lineColor(Color.parseColor("#e55e5e"))));
Point point = routeCoordinates.get(0);
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(point.latitude(), point.longitude()), 17));
}
I need to add more points and update the line. As you can see in the example line geometry is given to the source layer at the construction time. I couldn't find any api to add a point to the current line later.
Should I remove this line and redraw a new one ? Isn't there a better approach ?
You can add the "line-source" source and corresponding "lineLayer" layer once, and set the data contained by the source each time you want to add more points to update the line. Namely, each time you want to update the data rendered by the LineLayer:
Add the newly acquired coordinate to your existing GeoJSON source, stored in a variable called data. (I'd recommend storing new GeoJsonSource("line-source", ... in a data variable rather than creating it inline within the call to style#addSource, so that you can access it later to update).
Execute style.getSourceAs("line-source").setGeoJson(data).
Alternatively, you could use geoJsonSource.setGeoJson(Feature.fromGeometry(LineString.fromLngLats(updatedRouteCoordinates))) rather than setGeoJson(data), which might be more convenient depending on your use case.
You can modify the implementation according to your specific needs, but the general idea is that you only need to update the existing source's data, and not its corresponding layer, each time you want to update the line. This concept is described in the modify properties documentation for the Mapbox Maps SDK for Android. To quote the documentation:
sources and layers aren't immutable so they can be modified anytime during the map render
I would like to simulate an inheritance of Marker from Google Maps API V2. I know it's impossible to inherit from Marker because Marker is a final class and that's my problem.
My final goal: create a Marker (let's call this one MainPoint) which deploys 5 others Marker (let's call them Petal) when I click on it and hides them when I click again.
When Petals are deployed around MainPoint, thanks to onMarkerClickListener I can catch the marker but I can't identify if this marker is a MainPoint or a Petal.
If I could make Petal and MainPoint inherit from Marker or even put a tag on it, I would just have to check if this is a Petal or a MainPoint to know which method I have to call but with only the instance of a Marker, the only way I found is to check every instance of every MainPoint and its Petals if it's equal to the marker clicked.
I hope you can help me to find a way to design this situation.
I can't identify if this marker is a MainPoint or a Petal
Maintain a HashMap mapping petal Marker IDs to main point Marker IDs. Look up your Marker in the HashMap to find its associated main point, and if you get back null, you know that it is a main point.
I'm developing a android application with google maps v2 that draw polygons on the google maps. But now i have to identify a click on a certain polygon and popup a window.
I found this useful library on github
This library has the method containsLocation implemented. This method receives a LatLng (from click on the map) and a List (the polygon). This is fine but if i have 1 million polygon in the map i cant iterate all and test if a certain LatLng belongs to a certain Polygon. I remember that i can use a quadtree to get more performance and this library also implements a quadtree but it uses point. What is the best way of doing this? May i have to reimplement this quadtree for a quadtree of LatLng ? Or in each click i have to convert this click to a point and search on a point quadtree?
Regards
you cannot use a Point- Quadtree, you need an Object-Quadtree for your Polygons. An object quadree uses the bounding box of the polygon or any object for adding into the tree.
you dont need to consider latLong, use x,y with x= longitude, and y = Latitude.
Consider reading Hanan Sammet: Foundations of multidimensional data structures.
I think you need to implement a quadtree that stores the polygons, then query the tree to see which polygon (if any) contains the LatLng. If you search around I'm sure you can find a decent implementation.
I'm currently implementing GoogleMapsV2 and try to port the old functionality I had in MapsV1. in V1, I was able to subclass an OverlayItem and save the icon i put inside. Now I have to create a MarkerOption based on a model object, add it to the GoogleMap to get a Marker back.
Because the Marker class is final, and GoogleMaps isn't providing a Method to get a handle on it (like a SQLiteCursorFactory), I feel unable to get the icon back I put inside.
If i keep the MarkerOptions object, I could get back a BitmapDescriptor which has only one (obfuscated) method aW() which is returning a b object.
I'm quite shure that the Bitmap must be somewhere inside this object because its drawn on the GoogleMap. What is the best way to get it back from the marker.
I'm currently mapping the Marker to my model upon creation inside a HashMap<Marker, ModelObj> but from there I have to re-create the icon everytime I want to access it. This feels simply wrong, and I'm wondering if there is a better method of accessing it.
I'm quite shure that the Bitmap must be somewhere inside this object because its drawn on the GoogleMap.
That's far from certain. The map is rendered by another process. So, while the Bitmap is in that process, it may not be in yours.
What is the best way to get it back from the marker.
You don't. That's a write-only API.
I'm currently mapping the Marker to my model upon creation inside a HashMap but from there I have to re-create the icon everytime I want to access it.
Then cache it yourself. Nowadays, Marker has getId(), which is probably better than using Marker itself as the key. But then either tuck your icon into ModelObj or have a separate bitmap cache. You will have to determine for yourself if the CPU vs. RAM trade-off warrants caching or regenerating the icon.
Im trying to create a map using the service2media platform for mobile applications and i get this error - attempted index of non table : null on the line where i create a new map instance. Any idea why? The map view takes in coordinates and radius as parameters.
MapView ={}
function MapView:loadView()
local mapView = M2Map.newNativeMapView(Coordinate(0,0), 3000);
self:addSubView(mapView);
end
First of all you have to instantiate the Coordinate class using Coordinate.new(). Depending on the version of the platform you possibly have to use the MapView class instead of the M2Map class. In the latter case you have to rename your Lua class name in order to prevent name collision.
function MapView:loadView()
local mapView = M2Map.newNativeMapView(Coordinate.new(0,0), 3000);
self:addSubView(mapView);
end