Why do dynamically added symbols show up grey in Mapbox - java

When I tap the screen, a marker gets added to the middle of a Mapbox map. The first marker shows up as it is supposed to. However as soon as I add a second marker, the markers show up grey.
Here is the code I use to create the symbol source and the symbol layer, as well as the onMapClickListener where the features of the symbol source get updated with the new marker. All this code is in the onStyleLoaded method.
//Create the symbol source
Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_map_marker_blue, null);
Bitmap marker = BitmapUtils.getBitmapFromDrawable(drawable);
style.addImage(BLUE_MARKER_IMAGE, marker);
GeoJsonSource geoJsonSourceSymbol = new GeoJsonSource(SYMBOL_SOURCE_ID);
style.addSource(geoJsonSourceSymbol);
//Create the symbol layer
symbolLayer = new SymbolLayer(SYMBOL_LAYER_ID, SYMBOL_SOURCE_ID);
symbolLayer.setProperties(iconImage(BLUE_MARKER_IMAGE), iconOffset(new Float[] {0f, -10f}));
style.addLayer(symbolLayer);
mapboxMap.addOnMapClickListener(new MapboxMap.OnMapClickListener() {
#Override
public boolean onMapClick(#NonNull LatLng point) {
final LatLng mapTargetLatLng = mapboxMap.getCameraPosition().target;
Point mapTarget = Point.fromLngLat(mapTargetLatLng.getLongitude(),mapTargetLatLng.getLatitude());
pointList.add(mapTarget);
featureList.add(Feature.fromGeometry(mapTarget));
if (style.getLayer(SYMBOL_LAYER_ID) != null) {
GeoJsonSource geoJsonSourceSymbol = style.getSourceAs(SYMBOL_SOURCE_ID);
if (geoJsonSourceSymbol != null) {
geoJsonSourceSymbol.setGeoJson(FeatureCollection.fromFeatures(featureList));
}
}
return true;
}
});
Is there something I'm doing wrong or is it not possible to dynamically add symbols using data-driven styling?

Are you using an emulator? The Mapbox team already knows of SymbolLayer rendering issues on emulated devices:
https://github.com/mapbox/mapbox-gl-native/issues/10829
https://github.com/mapbox/mapbox-plugins-android/issues/1082

Related

Can not remove Polyline from Google Map, Android SDK

I have a problem removing a single polyline from my Google Map in Android.
There were other Users with similar questions but not many answers and none of them where helpful.
Inside the google dock, it's explained that you can remove a polyline with the .remove() function.
But in my case this does not work. Maybe the problem lays within the scope.
In my class I have defined:
Polyline polyline = null;
Then I have an OnClick Listener for my Map and two arrays. One with 2 Locations in it (for my polyline) and one that adds Markers when I click on the map.
if(test.size() == 2 && pol == false)
{
polylineOptions.color(Color.BLUE);
polylineOptions.addAll(test);
polyline = m_map.addPolyline(polylineOptions);
//polygonOptions.fillColor(Color.BLUE).addAll(test);
}
if(markerList.size() == 2)
{
pol = true;
polyline.remove();
}
When I click on the Map a polyline is drawn. Then I click again, and the markerList is now equal 2, it goes into the function but the polyline is not removed. Why? What can I do?

How to remove a symbol from a map

I am currently creating a map which updates based on users selection and displays 5 location closest to them. This works however when the user changes their selection the map updates and displays the 5 NEW locations as well as the 5 OLD locations.
I am not sure how to remove the old symbols.
public void displayResults(ArrayList allLocation) {
SymbolManager sm = new SymbolManager(mapView,map,styleMap);
sm.deleteAll();
SymList.clear();
sm.setIconAllowOverlap(true);
sm.setIconIgnorePlacement(true);
int count = 1;
for (LocationDetails a : allLocation
) {
// gets the distance from user to Location
double LocationLat = Double.parseDouble(a.getLatitude());
double LocationLng = Double.parseDouble(a.getLongitude());
float[] disResult = new float[1];
Location.distanceBetween(lat, lng, LocationLat, LocationLng, disResult);
results.append(count + ": " + a.getName() + " " + "\n");
distanceResults.append(Math.round(disResult[0]) + "m" + "\n");
SymbolOptions symbolOptions = new SymbolOptions()
.withLatLng(new LatLng(LocationLat, LocationLng))
.withIconImage("marker-11")
.withTextField(""+count)
.withIconColor("black")
.withIconSize(2.5f);
SymList.add(symbolOptions);
count++;
}
LatLngBounds latLngBounds = new LatLngBounds.Builder()
.include(SymList.get(0).getLatLng())
.include(SymList.get(1).getLatLng())
.include(SymList.get(2).getLatLng())
.include(SymList.get(3).getLatLng())
.include(SymList.get(4).getLatLng())
.build();
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 50), 2000);
for(SymbolOptions a : SymList){
sm.create(a);
}
SymList.clear();
}
I have been using mapbox for 3 months. After hours of research I discovered that on Android the only way to remove a Symbol or any element on the map was to reload all the elements from scratch. Unfortunately, there is currently no method to remove a single element.
So I suggest you create a container class in which to save your items.
If your use case only requires showing about five markers on the map at a time, it might be easier to use native sources and SymbolLayers rather than relying on the abstraction provided by the SymbolManager.
For example, this icon updates based on API response Android demo shows how to add a GeoJSON source and corresponding layer to the map, then update said source to get a different visual result. Basically all of the logic you will need is encapsulated here, but your GeoJSON will be a FeatureCollection of multiple (namely, 5) features rather than just one point.
So, you can set up your symbols similarly to how it's done in the linked example:
private void initSpaceStationSymbolLayer(#NonNull Style style) {
style.addImage("space-station-icon-id",
BitmapFactory.decodeResource(
this.getResources(), R.drawable.iss));
style.addSource(new GeoJsonSource("source-id"));
style.addLayer(new SymbolLayer("layer-id", "source-id").withProperties(
iconImage("space-station-icon-id"),
iconIgnorePlacement(true),
iconAllowOverlap(true),
iconSize(.7f)
));
}
, and then update the source's GeoJSON to the new locations closest to the user's position, similar to the updateMarkerPostion method:
private void updateMarkerPosition(LatLng position) {
// This method is where we update the marker position once we have new coordinates. First we
// check if this is the first time we are executing this handler, the best way to do this is
// check if marker is null;
if (map.getStyle() != null) {
GeoJsonSource spaceStationSource = map.getStyle().getSourceAs("source-id");
if (spaceStationSource != null) {
spaceStationSource.setGeoJson(FeatureCollection.fromFeature(
Feature.fromGeometry(Point.fromLngLat(position.getLongitude(), position.getLatitude()))));
}
}
// Lastly, animate the camera to the new position so the user
// wont have to search for the marker and then return.
map.animateCamera(CameraUpdateFactory.newLatLng(position));
}
A few modifications will need to be made, of course, but this option might be more direct for your implementation specifically.

lock map activity

In my application im trying to prevet the user to be able to scroll "free" around the map activity , i want the display content to be lock in some specific coordinates but the difficult part is to concatenate this with the ability of the camera geolocalization(GPS) to follow around the user .
i can for example try to add a move camera to the onLocationChanged and this will lock the camera in the region that i want evry time the user move , but this is not what i want , i just want to reset the camera if the user scroll in a zone that i dont want him to see , if you are browsing the map of Washington i want the camera to reset if the user goes for example on baltimora .
LatLng Washington = new LatLng(38.9150303, -77.1655794);
public void onLocationChanged(Location location) {
LatLng me = new LatLng(location.getLatitude(),location.getLongitude());
//LOCK CAMERA
mMap.moveCamera(CameraUpdateFactory.newLatLng(Washington));
//Marker Position
if (null != currentMarker) {
currentMarker.remove();
}
currentMarker = mMap.addMarker(new MarkerOptions().position(me).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
If you want the user to be able to move the map but restrict to a given area, the map offers you that option.
As mentioned here : Restricting the user's panning to a given area
private GoogleMap mMap;
// Create a LatLngBounds that includes the city of Adelaide in Australia.
private LatLngBounds ADELAIDE = new LatLngBounds(
new LatLng(-35.0, 138.58), new LatLng(-34.9, 138.61));
// Constrain the camera target to the Adelaide bounds.
mMap.setLatLngBoundsForCameraTarget(ADELAIDE);

How to implement open street map on android with infowindow on markers?

How to implement open street map on android with infowindow on markers?
OpenStreetMapTileProviderConstants.setUserAgentValue(BuildConfig.APPLICATION_ID);
openStreetMap = (MapView)findViewById(R.id.openmapview);
openStreetMap.setBuiltInZoomControls(true);
openStreetMapController = openStreetMap.getController();
openStreetMapController.setZoom(16);
openStreetMap.setMultiTouchControls(true);
GeoPoint initialLocation = new GeoPoint(lat , lng);
centerMap(initialLocation);
addLocation(lat ,lng , R.drawable.marker);}
This is my code and y want to add markers with it's infoWindows like googleMaps
A sample using marker was recently added. The original source is from osmbonuspack's tutorial
The sample is located here
The basic code is this
GeoPoint startPoint = new GeoPoint(38.8977, -77.0365); //white house
Marker startMarker = new Marker(mMapView);
startMarker.setPosition(startPoint);
startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
startMarker.setIcon(getResources().getDrawable(R.drawable.icon));
startMarker.setTitle("White House");
startMarker.setSnippet("The White House is the official residence and principal workplace of the President of the United States.");
startMarker.setSubDescription("1600 Pennsylvania Ave NW, Washington, DC 20500");
mMapView.getOverlays().add(startMarker);
mMapView.invalidate();
The osmdroid wiki contains a guide called How to use the osmdroid library. It contains a section about placing icons on the map with a click listener.
Basically you have to create a ItemizedOverlayWithFocus consisting of OverlayItems. Each OverlayItem comes with a title, a description and of course coordinates. The ItemizedOverlayWithFocus has to be added to your MapView.
There is the example from the wiki page:
//your items
ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
items.add(new OverlayItem("Title", "Description", new GeoPoint(0.0d,0.0d))); // Lat/Lon decimal degrees
//the overlay
ItemizedOverlayWithFocus<OverlayItem> mOverlay = new ItemizedOverlayWithFocus<OverlayItem>(items,
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
//do something
return true;
}
#Override
public boolean onItemLongPress(final int index, final OverlayItem item) {
return false;
}
});
mOverlay.setFocusItemsOnTap(true);
mMapView.getOverlays().add(mOverlay);

Why osmdroid not working in offline mode (multiple questions)?

I am working on the OSMdroid library, and wanted to make it offline so i used this code
mMapView.setUseDataConnection(false);
but in this condition it won't even display the map other than the graph page. But when i change the boolean to true it again starts working.
So how do i make it work completely offline?
I am also trying to get the poi so i have the following code
geoPoint= new GeoPoint(37.439974,-119.003906);
double north = 84;
double east = -180;
double south = -84;
double west = 180;
boundingBoxE6 = new BoundingBoxE6(north, east, south, west);
mMapView.setScrollableAreaLimit(boundingBoxE6);
mMapView.setMultiTouchControls(true);
Marker marker= new Marker(mMapView,mResourceProxy);
marker.setPosition(geoPoint);
mMapView.getOverlays().add(marker);
poiMarkers = new FolderOverlay(getActivity());
new connection().execute();
mMapView.invalidate();
public class connection extends AsyncTask{
#Override
protected Object doInBackground(Object[] objects) {
NominatimPOIProvider poiProvider = new NominatimPOIProvider();
pois=poiProvider.getPOICloseTo(geoPoint,"atm",50,1000);
return pois;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
mMapView.getOverlays().add(poiMarkers);
Drawable poiIcon = getResources().getDrawable(R.drawable.marker_poi_default);
if (o != null) {
for (POI poi : pois) {
Marker poiMarker = new Marker(mMapView);
poiMarker.setTitle(poi.mType);
poiMarker.setSnippet(poi.mDescription);
poiMarker.setPosition(poi.mLocation);
poiMarker.setIcon(poiIcon);
poiMarkers.add(poiMarker);
}
}else{
Toast.makeText(getActivity(),"null",Toast.LENGTH_SHORT).show();
}
}
}
But instead of getting the poi on the given geopint i get it somewhere else and everytime i mean whatever the code i change i don't get the poi in any other places other than that
http://nominatim.openstreetmap.org/search?format=json&q=[atm]&limit=50&bounded=1&viewbox=-1119.003906,1037.439974,880.996094,-962.560026
Is it possible to access poi in offline mode?
As for the offline tiles showing, are you sure you have the offline map tiles .ZIP-file stored in /mnt/sdcard/osmdroid/ (or whatever the path for your device's SDcard is, it just has to be within this folder in a subdirectory called osmdroid)?
A good tutorial that helped me can be found here: http://www.haakseth.com/?p=30
The OSMdroid TileSource will automatically look for this .ZIP-file if there is no internet connection to retrieve the tiles from. In the OpenStreetMapTileProviderConstants class there is this piece of code:
/** Base path for osmdroid files. Zip files are in this folder. */
public static final File OSMDROID_PATH = new File(Environment.getExternalStorageDirectory(),
"osmdroid");
So as you can see, you just need to have the osmdroid-directory in your SDcard folder, and everything should work just fine.
If you don't have a map tiles .ZIP yet, check out Mobile Atlas Creator for creating this.

Categories

Resources