How to implement mapbox SDK v10 to android app written in Java? - mapbox

I am trying to implement Mapbox SDK v10 in my android app that's completely written in Java.
I have been able to show the map and even the camera points to my current location but when I am trying to put a marker on the map I can't find the relevant codes in java because only kotlin codes are present
// Create an instance of the Annotation API and get the PointAnnotationManager. val annotationApi = mapView?.annotations val pointAnnotationManager = annotationApi?.createPointAnnotationManager(mapView) // Set options for the resulting symbol layer. val pointAnnotationOptions: PointAnnotationOptions = PointAnnotationOptions() // Define a geographic coordinate. .withPoint(Point.fromLngLat(18.06, 59.31)) // Specify the bitmap you assigned to the point annotation // The bitmap will be added to map style automatically. .withIconImage(YOUR_ICON_BITMAP) // Add the resulting pointAnnotation to the map. pointAnnotationManager?.create(pointAnnotationOptions)
So I have 2 questions-
1)How can I put an annotation or marker on the map using java?
2)On the other hand I have been able to use Mapbox SDK v9 successfully ,but it's marked as legacy so can I still use this SDK in my app or there can be some problem in the future if I use SDK v9?

These are the codes for adding a marker, polyline of polygon in mapbox10 java:
private void AddMarker(Point point)
{
AnnotationPlugin annotationApi = AnnotationPluginImplKt.getAnnotations(mapView);
CircleAnnotationManager circleAnnotationManager = CircleAnnotationManagerKt.createCircleAnnotationManager(annotationApi, new AnnotationConfig());
CircleAnnotationOptions circleAnnotationOptions = new CircleAnnotationOptions()
.withPoint(point)
.withCircleRadius(7.0)
.withCircleColor("#ee4e8b")
.withCircleStrokeWidth(1.0)
.withDraggable(true)
.withCircleStrokeColor("#ffffff");
circleAnnotationManager.create(circleAnnotationOptions);
}
private void DrawPolyLine() {
AnnotationPlugin annotationApi = AnnotationPluginImplKt.getAnnotations(mapView);
PolylineAnnotationManager polylineAnnotationManager = PolylineAnnotationManagerKt.createPolylineAnnotationManager(annotationApi,new AnnotationConfig());
PolylineAnnotationOptions polylineAnnotationOptions = new PolylineAnnotationOptions()
.withPoints(pointList)
.withLineColor("#ee4e8b")
.withLineWidth(4);
polylineAnnotationManager.create(polylineAnnotationOptions);
}
private void DrawPolygon(List<Point> myPointList) {
List<Point> pointList = myPointList;
pointList.add(myPointList.get(0));
List<List<Point>> polygonList = new ArrayList<>();
polygonList.add(pointList);
polygonAnnotationManager = PolygonAnnotationManagerKt.createPolygonAnnotationManager(annotationApi,new AnnotationConfig());
PolygonAnnotationOptions polygonAnnotationOptions = new PolygonAnnotationOptions()
.withPoints(polygonList)
.withFillColor("#ee4e8b")
.withFillOpacity(0.5);
PolygonAnnotation polygonAnnotation = polygonAnnotationManager.create(polygonAnnotationOptions);
}
remember for marker annotation we have to types: Point annotation and Circle annotation but their implementation of them are the same.

Related

Display multiple InfoWindows using osmdroid

I want to display multiple marker infoWindows to mark different routes. However, only the last created one is being displayed.
My (relevant) marker creation code is:-
if (routes.size() < 3) {
Polyline roadOverlay = new Polyline();
roadOverlay.setColor(polyClr.get(routes.size()));
roadOverlay.setWidth(5f);
roadOverlay.setPoints(waypoints);
// Add Route Marker
Marker m = new Marker(map);
double d = roadOverlay.getDistance()*5/8000;
GeoPoint midpt = waypoints.get((int)(waypoints.size()/2));
m.setTitle(rteDesc.get(routes.size())+" - "+String.format("%.2f miles",d));
m.setSnippet("Tap to Save");
m.setIcon(getResources().getDrawable(R.drawable.transparent));
m.setPosition(midpt);
m.showInfoWindow();
rtemkrs.add(m);
routes.add(roadOverlay);
}
and the display code is:-
for (int j = rtemkrs.size()-1; j>=0; j--) {
map.getOverlays().add(rtemkrs.get(j));
}
map.invalidate();
I'm using osmdroid v 6.1.0 and osmbonuspack v 6.6.0
How can I display multiple marker infoWindows?
By default, all markers use one shared view as their InfoWindow. Therefore only the one view can be displayed.
But it is possible to change the behaviour:
You'll need to create a MarkerInfoWindow instance for each marker, for example this his how the default one is created: new MarkerInfoWindow(R.layout.bonuspack_bubble, mMapView);
You'll have to pass the view to the marker by calling marker.setInfoWindow(...) (see method's javadoc) for each marker

Rotate and change position for markers in latest MapBox SDK 6.7

Mapbox Android SDK: 6.7.0
The requirement in the application we are developing is that we have to add multiple markers in different LatLng positions and also rotate them with some bearing. In the old mapbox version(4.2.1), we could do it without any issues.
////Working code with MapBox SDK 4.2.1////
MarkerViewOptions markerViewOptions = new MarkerViewOptions();
IconFactory iconFactory = IconFactory.getInstance(this);
Icon arrowIcon = iconFactory.fromResource(R.drawable.compass_needle);
markerViewOptions.icon(arrowIcon);
markerViewOptions.position(new LatLng(position)).rotation((float) headDirection);
marker = mapboxMap.addMarker(markerViewOptions);
////For updating////
marker.setPosition(new LatLng(aircraftLocation));
marker.setRotation((float) headDirection);
mapboxMap.updateMarker(marker);
In the latest Mapbox update, MarkerView and MarkerViewOptions is deprecated. We are trying to achieve the same functionality with Marker and MarkerOptions. But we are unable to rotate the markers.
We also tried using the SymbolLayer. Rotate function is available here but we are unable to set a LatLng position for a marker.
How to proceed with the latest SDK to achieve this?
This can be achieved by symbol layer in the latest SDK 6.7.0.
To add a marker:
Bitmap compassNeedleSymbolLayerIcon = BitmapFactory.decodeResource(
getResources(), R.drawable.compass_needle);
mapboxMap.addImage(AIRCRAFT_MARKER_ICON_ID, compassNeedleSymbolLayerIcon);
GeoJsonSource geoJsonSource = new GeoJsonSource(GEOJSON_SOURCE_ID, Feature.fromGeometry(
Point.fromLngLat(longitude, latitude)));
mapboxMap.addSource(geoJsonSource);
SymbolLayer Layer = new SymbolLayer(AIRCRAFT_LAYER_ID, GEOJSON_SOURCE_ID)
.withProperties(
PropertyFactory.iconImage(AIRCRAFT_MARKER_ICON_ID),
PropertyFactory.iconRotate((float) headDirection),
PropertyFactory.iconIgnorePlacement(true),
PropertyFactory.iconAllowOverlap(true)
);
mapboxMap.addLayer(layer);
To rotate or changing the position of the marker:
GeoJsonSource source = mapboxMap.getSourceAs(GEOJSON_SOURCE_ID);
if (source != null) {
source.setGeoJson(Feature.
fromGeometry(Point.fromLngLat(longitude, latitude)));
layer.setProperties(
PropertyFactory.iconRotate((float) headDirection)
);
}
This above code may not work sometimes when you add the marker in the onMapReady() callback. Because onMapReady() is called before all styles are loaded. Hence add the marker in addOnDidFinishLoadingStyleListener() callback.
mapView.addOnDidFinishLoadingStyleListener(new MapView.OnDidFinishLoadingStyleListener() {
#Override
public void onDidFinishLoadingStyle() {
//add marker here
}
});

Get leaflet marker from a layer

I'm new to leaflet and am trying to implement a set of markers with different CSS-styles.
So, I am aware that after adding a marker to a map I can access different CSS-attributes by calling getElement() on my marker for example:
marker.addTo(map);
marker.getElement().style.borderColor = '#000';
This works just fine, but when adding a marker to a layer, this can no longer be used since a TypeError occurs (getElement() is undefined). Here is the example code where the error occurs:
myLayer.addLayer(marker);
marker.getElement().style.borderColor = '#000';
Am I overlooking a simpler way to set CSS-Attributes for markers and divicons that are added to layers or is there a similar way to access layer-added markers and divicons in JavaScript?
So I found a solution that is working for me.
The idea is to extend the function that is used to create the icon.
Last answer here github.com/Leaflet/Leaflet/issues/5231 helped a lot.
var borderSize = ...;
L.DivIcon.Custom = L.DivIcon.extend({
createIcon: function(oldIcon) {
var icon = L.DivIcon.prototype.createIcon.call(this, oldIcon);
icon.style.borderSize = borderSize;
...
return icon;
}
})
var icon = new L.DivIcon.Custom({
...
});
var ll = L.latLng(entry.Longitude, entry.Latitude);
var marker = L.marker(ll, {
icon: icon
})
this.myLayer.addLayer(marker);
Welcome to SO!
When not added onto a map (since your parent myLayer may not be added to the map itself), a marker does not have any element.
If you do not need to change too many styles individually and dynamically, you might rather use the className option of your Icon / DivIcon.

leafeltjs (mapbox) z-index ordering not working

Another developer created our original map but I'm tasked with making some changes. One of these is making sure the activated marker is brought to the front when clicked on (where it is partially overlapped by other markers).
The developers have used mapbox 2.2.2.
I have looked at leafletjs's docs, have followed some instructions on other posted solutions (e.g. solution one and solution two). Neither of these makes any difference.
Examining the marker in Chrome's console I can see the value of options.zIndexOffset is being set (10000 in my test case). I've even set _zIndex to an artificially high value and can see that reflected in the marker's data structure. But visually nothing is changing.
This is how the map is set up initially. All features are from a single geojson feed:
L.mapbox.accessToken = '<access token here>';
var map = L.mapbox.map('map', 'map.id', {
}).setView([37.8, -96], 3);
var jsonFeed, jsonFeedURL;
var featureLayer = L.mapbox.featureLayer()
.addTo(map)
.setFilter(function (f) {
return false;
});
$.getJSON(jsonFeedURL, function (json) {
jsonFeed = json;
jsonFeedOld = json;
// Load all the map features from our json file
featureLayer.setGeoJSON(jsonFeed);
}).done(function(e) {
// Once the json feed has loaded via AJAX, check to see if
// we should show a default view
mapControl.activateInitialItem();
});
Below is a snippet of how I had tried setting values to change the z-index. When a visual marker on the featureLayer is clicked, 'activateMarker' is called:
featureLayer.on('click', function (e) {
mapControl.activateMarker(e);
});
The GEOjson feed has urls for the icons to show, and the active marker icon is switched to an alternative version (which is also larger). When the active feature is a single Point I've tried to set values for the marker (lines commented out, some of the various things I've tried!)
activateMarker: function (e) {
var marker = e.layer;
var feature = e.layer.feature;
this.resetMarkers();
if (feature.properties.hasOwnProperty('icon')) {
feature.properties.icon['oldIcon'] = feature.properties.icon['iconUrl'];
feature.properties.icon['iconUrl'] = feature.properties.icon['iconActive'];
feature.properties.icon['oldIconSize'] = feature.properties.icon['iconSize'];
feature.properties.icon['iconSize'] = feature.properties.icon['iconSizeActive'];
}
if (feature.geometry.type == 'Point') {
marker.setZIndexOffset(10001);
marker.addTo(featureLayer);
}
//featureLayer.setGeoJSON(jsonFeed);
}
Any advice would be greatly appreciated! I'm at the point where I don't know what else to try (and that's saying something).
What probably happens is that you just flush your markers with the last call to .setGeoJSON():
If the layer already has features, they are replaced with the new features.
You correctly adjust the GeoJSON data related to your icon, so that when re-created, your featureLayer can use the new values to show a new icon (depending on how you configured featureLayer).
But anything you changed directly on the marker is lost, as the marker is removed and replaced by a new one, re-built from the GeoJSON data.
The "cleanest" way would probably be to avoid re-creating all features at every click.
Another way could be to also change something else in your GeoJSON data that tells featureLayer to build your new marker (through the pointToLayer option) with a different zIndexOffset option.

How to transform a GWT OpenLayers VectorFeature?

I am using OpenLayers GWT. I want to put an GeoJSON shape on top of a Google Maps layer. I have done as follows:
String gson = "{here I put a valid GeoJSON string}";
GeoJSON geoJSON = new GeoJSON();
VectorFeature[] vf = geoJSON.read(gson);
myShapeLayer.addFeature(vf[0]);
The shape is showing on the map, but not a the right position. I think I have to transform the Vector to EPSG:900913 but I don't know how to do that with the VectorFeature. There is no transform function to use.
How can I apply the transformation to a GWT VectorFeature?
This question is not getting responses. I would like to explain better what I want to know:
In javascript Openlayers you can do:
var projWGS84 = new OpenLayers.Projection("EPSG:4326");
var proj900913 = new OpenLayers.Projection("EPSG:900913");
feature.geometry.transform(projWGS84, proj900913);
How can I do the same in the GWT version of OpenLayers?
Thanks in advance.
OpenLayers-GWT is missing the GeoJSON constructor that will take an options parameter, this has to be added in the OpenLayers-GWT source. In the mean time this has been added to the KML Vector class. So now you can do like this:
String kmlString = "{<string with KML>}";
FormatOptions formatOptions = new FormatOptions();
formatOptions.setInternalProjection(new Projection("EPSG:900913"));
formatOptions.setExternalProjection(new Projection("EPSG:4326"));
KML kml = new KML(formatOptions);
VectorFeature[] vf = KML.read(kmlString);
myShapeLayer.addFeature(vf[0]);
In the same way it should be added to the GeoJSON class to make the tranformation work.