While trying to add marker to mapbox using symbol layer, the marker was not visible.
Tried to add marker as shown below,
mapView.getMapAsync(m -> {
isMapReady = true;
mapboxMap = m;
mapboxMap.addOnMapClickListener(MapViewFragment.this);
addMarkerToSymbolLayer(45);
updateCameraPosition(location); });
private void updateCameraPosition(Location location){
if (mapboxMap != null) {
LatLng latLong = new LatLng();
if (location != null) {
latLong.setLatitude(location.getLatitude());
latLong.setLongitude(location.getLongitude());
}
final CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLong)
.build();
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
mapView.postDelayed(() -> mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), AppConstants.MAP_CAMERA_ANIMATE_DURATION_MS_5000), 100);
private void addMarkerToSymbolLayer(float headDirection) {
GeoJsonSource geoJsonSource = new GeoJsonSource("geojson-source",
Feature.fromGeometry(Point.fromLngLat(77.6387, 12.9610)));
mapboxMap.addSource(geoJsonSource);
Bitmap compassNeedleSymbolLayerIcon = BitmapFactory.decodeResource(
getResources(), R.drawable.compass_needle);
mapboxMap.addImage("compass-needle-image-id", compassNeedleSymbolLayerIcon);
SymbolLayer aircraftLayer = new SymbolLayer("aircraft-layer", "geojson-source")
.withProperties(
PropertyFactory.iconImage("compass-needle-image-id"),
PropertyFactory.iconRotate(headDirection),
PropertyFactory.iconIgnorePlacement(true),
PropertyFactory.iconAllowOverlap(true)
);
mapboxMap.addLayer(aircraftLayer);
}
If addMarkerToSymbolLayer() is called after moving camera then the marker is visibile. Why is that adding marker dependent on camera position? I have to move camera many times to meet my requirement. How to handle this?
Also in the Deprecated MarkerView and MarkerViewOptions I didnt have any issues while adding marker.
I noticed that if given a delay of 100ms while calling the function addMarkerToSymbolLayer(45), the marker is visible and things work fine !
The onMapReady() is called even before all the styles have been loaded. It is necessary that all styles be loaded before adding a symbol layer. Add the following listener and call for adding marker inside it.
mapView.addOnDidFinishLoadingStyleListener(new MapView.OnDidFinishLoadingStyleListener() {
#Override
public void onDidFinishLoadingStyle() {
}
});
Related
I'm trying to add a tap listener to my map markers on my map to show an info-bubble to show details about that location in my Flutter app. I tried to use the Here Maps Map Pin option but I can't seem to combine on-tap gestures with creating a widget pin. I saw that the JavaScript SDK has a function to add info-bubble to map markers. Is there a way to do that in Flutter apart from the Map Pins?
This is a for loop I wrote to go through the list of Map markers on the map to create the Widget pin for each of them :
for (var a = 0; a < _mapMarkerList.length; a++) {
_hereMapController.gestures.tapListener =
TapListener((Point2D touchPoint) {
_hereMapController.viewToGeoCoordinates(touchPoint);
_hereMapController.pinWidget(
_createWidget('Here is my label', Color(0xFFFCAE06)),
_mapMarkerList.elementAt(a).coordinates);
});
}
You should not create a tap listener multiple times for each marker. Instead create only one tap listener. And then pick a marker with _hereMapController.pickMapItems(). Inside the callback you can create a map view pin.
void _setTapGestureHandler() {
_hereMapController.gestures.tapListener = TapListener((Point2D touchPoint) {
_pickMapMarker(touchPoint);
});
}
void _pickMapMarker(Point2D touchPoint) {
double radiusInPixel = 2;
_hereMapController.pickMapItems(touchPoint, radiusInPixel, (pickMapItemsResult) {
if (pickMapItemsResult == null) {
// Pick operation failed.
return;
}
List<MapMarker> mapMarkerList = pickMapItemsResult.markers;
int listLength = mapMarkerList.length;
if (listLength == 0) {
print("No map markers found.");
return;
}
MapMarker topmostMapMarker = mapMarkerList.first;
// Now create a map view pin based on this marker's coordinates.
});
}
See this example app for more context: https://github.com/heremaps/here-sdk-examples/blob/d07e4af93b2db946a1f97fdc12cfd6f4b0a760fc/examples/latest/navigate/flutter/map_items_app/lib/MapItemsExample.dart#L306
This is crazy, add marker doesn't seem to do what it suppose to do. Adding marker does nothing:
{
if(!isVisible())
return;
mPinBitmapUtils.retrievePinBitmapAsync(getContext(), recommendation, new OnPinBitmapProcessed()
{
#Override
public void onBitmapProcess(final Pin reco, PinType pinType, Map<String, String> directories)
{
if(!isVisible())
return;
recommendation.setName(pinType.getName());
new AsyncTask<String, Void, PinMarkerOptions>()
{
#Override
protected PinMarkerOptions doInBackground(String... strings)
{
IconFactory iconFactory = IconFactory.getInstance(getContext());
Bitmap bitmap = Utils.getBitmapFromFile(getContext()
, new File(strings[0])
, (int) Utils.convertDpToPixel(48, getContext())
, (int) Utils.convertDpToPixel(48, getContext()));
Icon icon = iconFactory.fromBitmap(bitmap);
LatLng position = new LatLng();
position.setLatitude(recommendation.getLatitude());
position.setLongitude(recommendation.getLongitude());
PinMarkerOptions markerOption = new PinMarkerOptions();
markerOption.setPosition(position);
markerOption.setMetaData(recommendation.getJSON().toString());
if(icon != null)
markerOption.setIcon(icon);
return markerOption;
}
#Override
public void onPostExecute(PinMarkerOptions marker)
{
mMapboxMap.addMarker(marker);
}
}.execute(directories.get(Constants.BLUE_PIN));
}
});
}
Every time I called addMarkers or addMarker its not being shown. I checked the size of the MapBox map instance and it indeed show it increased in size. This happens especially when I remove a marker, or called MapBoxMap#clear(). Nothing happens afterwards.
I am using MapBox API v4.2.2.
There is one problem with markers - you can't add them on top of your layers.
If that is a case, then you should use SymbolLayer for that purpose.
Info about markers from documentation.
Example of how use SympolLayer with BubbleLayout to create a marker with text inside.
When hovering over a marker using GMap.NET, it does not fire the events:
private void gMapControl1_OnMarkerEnter(GMapMarker item)
{
currentMarker = item;
}
private void gMapControl1_OnMarkerLeave(GMapMarker item)
{
currentMarker = null;
}
Here is the code that creates the marker:
// Add marker
currentMarker = new GMarkerGoogle(new PointLatLng(y, x), GMarkerGoogleType.yellow_small);
currentMarker.IsHitTestVisible = false;
currentMarker.Tag = iCurrentPolygon + "." + iCurrentPolygonPointIndex;
top.Markers.Add(currentMarker);
I can add markers but when I hover over them it does not execute the onMarkEnter/onMarkLeave
I guess you need to set IsHitTestVisible to true in order for the marker to receive event notifications.
I have a FragmentActivity with a GoogleMap inside. It correctly receives the user location in onLocationChanged, where I try to use the user location to center the map:
#Override
public void onLocationChanged(Location loc)
{
if (centerMap && mMap != null)
{
LatLng location = new LatLng(loc.getLatitude(), loc.getLongitude());
CameraPosition pos = new CameraPosition.Builder().target(location).zoom(12).build();
CameraUpdate cu = CameraUpdateFactory.newCameraPosition(pos);
mMap.animateCamera(cu);
// centerMap = false;
Log.e(getClass().getSimpleName(), "lat = " + location.latitude + " long = " + location.longitude);
}
}
This code actually worked now and then (maybe only once), and only during a debug session where I put a breakpoint inside the if statement. I don't understand what's wrong. The onLocationChanged method gets called regularly, it logs the position it received, that implies it entered the if condition, but the map does not move an inch from the lat=0,long=0 initial position (Africa).
Any clues?
EDIT: I must have something badly broken in my code: even markers do not show up, here is how I add them to the map
mMap.addMarker(new MarkerOptions()
.position(new LatLng(lat, lng))
.title("title")
.draggable(false)
.visible(true));
and the "My location" icon is not showing up either, even if I called
mMap.setMyLocationEnabled(true);
in onCreate(). Trying to exclude martians and such, I've already updated Eclipse, ADT and all the rest to the latest available versions.
For some reason (unknown to me), moving the map initialization from onCreate() into the first invocation of onLocationChange() did the trick. Now my onCreate() is simply
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.map_activity);
}
my onStart() is:
#Override
protected void onStart()
{
super.onStart();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(
LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the update interval to 5 seconds
mLocationRequest.setInterval(UPDATE_INTERVAL);
// Set the fastest update interval to 1 second
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationClient = new LocationClient(this, this, this);
mLocationClient.connect();
}
#Override
public void onConnected(Bundle arg0)
{
mLocationClient.requestLocationUpdates(mLocationRequest, this);
}
and my onLocationChange() is
#Override
public void onLocationChanged(Location loc)
{
if (mMap == null)
{
mapFragment = SupportMapFragment.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager()
.beginTransaction();
fragmentTransaction.add(R.id.mapcontainer, mapFragment);
fragmentTransaction.commit();
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
mMap.getUiSettings().setAllGesturesEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setCompassEnabled(true);
mMap.setMyLocationEnabled(false);
LatLng location = new LatLng(loc.getLatitude(), loc.getLongitude());
CameraPosition pos = new CameraPosition.Builder().target(location).zoom(12).build();
CameraUpdate cu = CameraUpdateFactory.newCameraPosition(pos);
mMap.animateCamera(cu);
if (mLocationClient.isConnected())
mLocationClient.removeLocationUpdates(this);
mLocationClient.disconnect();
Log.e(getClass().getSimpleName(), "lat = " + location.latitude + " long = " + location.longitude);
}
}
It works, but now I have a different problem (the map seems to ignore touch events). I'm going to create a separate question for that.
I use the branflake2267 google maps API for GWT (https://github.com/branflake2267/GWT-Maps-V3-Api).
I would like to display a title below a marker.
My location:
final LatLng latlng = LatLng.newInstance(47.4125, -0.861944);
The icon marker (it is the correct location on the map)
MarkerImage icon = MarkerImage.newInstance("/images/maps/pin_workshop.png", Size.newInstance(21, 34), Point.newInstance(0, 0), Point.newInstance(10, 34));
MarkerImage shadow = MarkerImage.newInstance("/images/maps/shadow.png", Size.newInstance(40, 37), Point.newInstance(0, 0), Point.newInstance(12, 35));
MarkerOptions options = MarkerOptions.newInstance();
options.setPosition(latlng);
options.setMap(map);
options.setTitle("Factory");
options.setIcon(icon);
options.setShadow(shadow);
Marker marker = Marker.newInstance(options);
The overlay with the title (Incorrect position in the map...):
final DivElement div = Document.get().createDivElement();
OverlayView.newInstance(map, new OverlayViewOnDrawHandler() {
#Override
public void onDraw(OverlayViewMethods methods) {
Point position = methods.getProjection().fromLatLngToDivPixel(latlng);
div.getStyle().setPosition(Position.ABSOLUTE);
div.getStyle().setLeft(position.getX(), Unit.PX);
div.getStyle().setRight(position.getY(), Unit.PX);
div.setInnerText("Factory");
}
},
new OverlayViewOnAddHandler() {
#Override
public void onAdd(OverlayViewMethods methods) {
methods.getPanes().getOverlayLayer().appendChild(div);
}
},
new OverlayViewOnRemoveHandler() {
#Override
public void onRemove(OverlayViewMethods methods) {
div.removeFromParent();
}
});
I try different version of the library (3.09 build 17, 3.10.0-alpha-6), and also different panes (getMapPane(), getFloatPane()) without success...
Ok, just using setLeft and setRight instead of setLeft and setTop...