I'm using the SymbolManager to display two symbols on the map. Here is an example:
The dark symbol is because of the fact that I'm testing the project on the Emulator, but the Line goes under the symbol, as it should be. The problem comes with the other symbol (finish flag). After I'm ready with the drawing of the line, the following code block is called:
symbolManager = new SymbolManager(mapView,mMapboxMap,style);
symbolManager.setIconAllowOverlap(true);
symbolManager.setIconIgnorePlacement(true);
SymbolOptions symbolOptionsFinishFlag = new SymbolOptions()
.withIconImage(IMAGE_FINISH_FLAG)
.withIconSize(2.0f)
.withLatLng(newLatLngs.get(newLatLngs.size()-1));
symbolManager.create(symbolOptionsFinishFlag);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.includes(newLatLngs);
LatLngBounds bounds = builder.build();
final CameraUpdate cu = new CameraUpdateFactory().newLatLngBounds(bounds,300);
mMapboxMap.easeCamera(cu,5000);
I checked some examples in the Mapbox site and it seems to be correct. However, the Symbol is under the Line, how can I bring on top of it?
If you are using a LineLayer, when adding it to the map use style.addLayerBelow(lineLayer, symbolManager.layerId)
This answer is about how to do this in Mapbox SDK v9. All AnnotationManager subclasses have a constructor which allows you to mention which layerId this should be below.
For example, in LineManager, we have this constructor
LineManager(MapView mapView, MapboxMap mapboxMap, Style style, java.lang.String belowLayerId)
Another method which will be needed here is the getLayerId method in the AnnotationManager class which returns the id used by a certain layer.
getLayerId
public java.lang.String getLayerId()
Returns a layer ID that annotations created by this manager are laid out on. This reference can be used together with Style#addLayerAbove(Layer, String) or Style#addLayerBelow(Layer, String) to improve other layers positioning in relation to this manager.
Returns:
underlying layer's ID
So say there are 3 elements on the map, a circle, a line and a symbol and we need to show the circle at the bottom, then the line above and finally the symbol at the top most.
So we will create our AnnotationManagers in this way -
val symbolManager = SymbolManager(mapView, map, map.style!!)
val lineManager = LineManager(mapView, map, map.style!!, symbolManager.layerId)
val fillManager = FillManager(mapView, map, map.style!!, lineManager.layerId)
What we're doing here is that while creating the lineManager object, we pass the layerId of the symbolManager which ensures that the Lines created using LineManager are always below the Symbols created using the SymbolManager. And the same for FillManager being below the lineManager object.
Although SymbolManagers can be useful means for providing an abstraction over the methods needed to add symbols to a map, you may get some more flexibility by working with native SymbolLayers directly. This example shows how to add symbol layer icons to a map, and this example shows how to specify layer ordering when new layers are added. So, by adding two symbol layers for your start and finish icons, and a line layer for the line between them, you could use style.addLayerBelow(finishFlagLayer, "name_of_line_layer").
Related
So currently I am making two symbol layers and GeoJsonSource for two types of symbol in my code - one set of symbols are active and another set is inactive symbols. I am doing this because I have two sets of symbols, therefore, I have made two GeoJsonSource.
val source_Active = GeoJsonSource("GeoJsonSourceActive", FeatureCollection.fromFeatures(listoflnglat_active),GeoJsonOptions().withCluster(true).withClusterMaxZoom(16).withClusterRadius(40))
val source_Passive = GeoJsonSource("GeoJsonSourcePassive", FeatureCollection.fromFeatures(listoflnglat_passive),GeoJsonOptions().withCluster(true).withClusterMaxZoom(16).withClusterRadius(40))
style.addSource(source_Active)
style.addSource(source_Passive)
val symbolLayerActive = SymbolLayer("Active","GeoJsonSourceActive")
val symbolLayerPassive = SymbolLayer("Passive","GeoJsonSourcePassive")
symbolLayerActive.withProperties(PropertyFactory.iconImage("marker-icon-active"))
symbolLayerPassive.withProperties(PropertyFactory.iconImage("marker-icon-passive"))
style.addLayer(symbolLayerActive)
style.addLayer(symbolLayerPassive)
Can I do it in a single layer because I want to perform clustering and I want that all icons cluster into one single icon after a certain level of zoom out
I've been searching for an answer for this but since i couldn't find any, i'll post the question.
I have a plot drawn, with a list below showing some data, one of the parameters of each row is drawn in the plot.
I'm trying to change the color of the point when the user clicks in one of the views of the list, to reflect in the plot that the row matches the point, but i haven't been able to replicate it.
There is any way to get an specific point of the graph, to change its color?
Thanks in advance.
I don't know if what you are trying to do is possible but you can try to add a serie to your plot containing the point that you want to highlight when user clicks. When a new click is done you just need to remove the added serie and add a new one containing the new point.
The added serie must have a different style so you can see the "changed color" and must be the last added serie so it will be in forground.
Hope it helps
Edit
What you can do to adapt it to your use case is to extend a XYPlot class, create a SeriesType highlightedPoint property and add a method like (not tested) :
public void highlightPoint(Number x, Number y, FormatterType formatter){
// if there is already a highlighted point we remove it (we want to highlight just one point)
if(highlightedPoint != null) {
removeSeries(highlightedPoint);
highlightedPoint = null;
}
// we need to highlight the new point, which means adding a serie on top of the others
highlightedPoint = new SimpleXYSeries("Highlighted Point");
highlightedPoint.addFirst(x,y);
addSeries(highlightedPoint, formatter);
}
You just need to call this method on your plot instance each time user clicks on your list.
I am able to implement SKAnnotation to set a single annotation in skmaps
Now i just want to add multiple annotations in skmaps map android
So here is the code snippet .. Any help will be appreciated ....
SKAnnotation annotation1 = new SKAnnotation(10);
// set annotation location
annotation1.setLocation(new SKCoordinate(-122.4200, 37.7765));
// set minimum zoom level at which the annotation should be visible
annotation1.setMininumZoomLevel(5);
// set the annotation's type
annotation1.setAnnotationType(SKAnnotation.SK_ANNOTATION_TYPE_RED);
// render annotation on map
mapView.addAnnotation(annotation1, SKAnimationSettings.ANIMATION_NONE);
I have looked everywhere and didn't get anything useful on how to implement this .....
Make an array that contains multiple coordinate data. Use a for loop to create an annotation for every single object in your array. Like this:
for(int i=0;i<coordinatesArray.count;i++) {
SKAnnotation annotation1 = new SKAnnotation(10);
// set annotation location
annotation1.setLocation(new SKCoordinate(latitude, longitude));
// set minimum zoom level at which the annotation should be visible
annotation1.setMininumZoomLevel(5);
// set the annotation's type
annotation1.setAnnotationType(SKAnnotation.SK_ANNOTATION_TYPE_RED);
// render annotation on map
mapView.addAnnotation(annotation1, SKAnimationSettings.ANIMATION_NONE);
}
get the latitude and longitude from your coordinatesArray object i
I'm trying to implement app in which you can add your own marker which will be given a shutdown time. To do so I need to know how to manage my markers. Let's say I have array list of users with assigned unique ID.
private ArrayList<User> userList = new ArrayList<>();
Then I will create array list of markers which will contain information like Latitude, Longitude, Title, owner's ID and deadline.
private ArrayList<MyMarker> mMarkersArray = new ArrayList<MyMarker>();
Next whenever user will activate add marker method, new marker will be pushed to my list of markers. Ideologically everything seems nice and easy, furthermore creating new object looks like this:
Marker mMarker = mMap.addMarker(new MarkerOptions() (...) );
but when it comes to managing specific markers it seems like I'm missing something. There will be some trigger method which will check the deadline of all markers (or rather first one on the 'sorted by deadline' list) and then it should remove (not hide, because I think it would be inefficient from the memory point of view). How to achieve this? I can't add some custom variable like ID to markers (so I could then find the one I'm interested in) and I'm a bit lost.
There is a way to achieve this by clearing whole map and then rendering again all markers except the inactive, but as far as I'm concerned it's very inefficient and there has to be better solution.
If you want to remove a specific marker from the map, you can just call the remove(). method.
Sample code to remove a marker from MapView and HashMap:
for (Marker marker : hm.keySet()) {
if (hm.get(marker).equals(deadline)) {
marker.remove();
hm.remove(marker);
}
}
You dont need to clear the entire MapView, if you just call remove() method on specific marker.
my problem is as follows.
I am creating multiple itemized overlays. (because every overlay gets a different drawable)
I customized the itemized overlay class, but when i add it to the mapview overlays, the class is transformed into an overlay class.
to make it worse i got 3 classes creating overlays on the same map. each class represents an item on the map with it's own intelligence behind it.
the problem i now have is that i want to remove an overlay, but i can not be sure that the index i inserted it on, is also the index it has when i try to remove it. (the other classes might have inserted an overlay in the mean time)
the classes are self updating, so i do not want a solution that fires an update or delete event from the main class. (the whole point is to add a class and forget about it)
so my question would be: how can i identify which layer is which when i want to call a remove on that layer. i think the information is available, but i do not know how to get to it.
this is the code i am using to add the overlay
OverlayItem overlayitem = new OverlayItem(p,myNaam ,myOmschrijving );
LocationOverlay = new MyLocationOverlay(drawable, myContext);
LocationOverlay.SetLocation(i,overlayitem);
myOverlays.add(LocationOverlay);
You can set a certain integer as a position for every overlays
something like that :
mapView.getOverlays().add(0,myScaleBarOverlay);
and when you want ro remove this call:
mapView.getOverlays().remove(0);
mapView.invalidate();
Regard
You don't have to remove specific layer. You can remove an overlay specified by it's reference (e.g. myOverlay).
LocationOverlay myOverlay = new MyLocationOverlay(drawable, myContext); //`you forgot the name of variable`
mapView.getOverlays().remove(myOverlay);