I have to modify the image of a SKAnnotation.
Annotation builder code:
private SKAnnotation getAnnotationFromView (int id,int minZoomLvl, View view) {
SKAnnotation annotation = new SKAnnotation();
SKAnnotationView annotationView = new SKAnnotationView();
annotationView.setView(view);
annotation.setUniqueID(id);
annotation.setOffset(new SKScreenPoint(annotationView.getWidth()/2, annotationView.getHeight()/2));
annotation.setAnnotationView(annotationView);
annotation.setMininumZoomLevel(minZoomLvl);
return annotation;
}
Now my problem is to update the annotation/image to the current state (position, orientation). Is there a way doing that without re adding the annotation? Looking into the documentation I found mapView.updateAnnotation() but it seems to work just for images added with annotation.setImagePath(imagePath)
Can someone help me with that?
Unfortunately no.
There is an inconsistency in the implementation (we'll address that in a future update) that allows one to reposition only annotations with the icon taken from an file.
If you'd like to reposition an (any) annotation you could/should remove it and add it again.
If you'd like to change the icon/view - then the updateAnnotation API should do the job
Related
I have a dataset of polylines, markers and polygons stored as lat/lon data in a CSV file that need plotting in Android MapBox. I'm able to do this easily using mapboxmap.addPolyline, addMarker and addpolygons, but after adding hundreds of points scrolling the map and viewing the data on an Android phone becomes very slow.
Am I going about this wrongly? Is there a more efficient way to plot many data points that i'm supposed to be using?
What version of the Maps SDK are you using? Your use of addPolyline/addMarker/etc. makes me think that you're using a very outdated version. Please try using 8.5.0 and using sources/layers: https://docs.mapbox.com/android/maps/overview/data-driven-styling/
In general, you should use the lat/lon data in the CSV file to create Feature objects. Use them to create a FeatureCollection and then add/style layers.
Setting up a LineLayer
mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() {
#Override
public void onStyleLoaded(#NonNull Style style) {
Feature polygonFeature = Feature.fromGeometry(Polygon.fromLngLats());
Feature lineStringFeature = Feature.fromGeometry(LineString.fromLngLats());
Feature pointFeature = Feature.fromGeometry(Point.fromLngLat());
FeatureCollection featureCollection = FeatureCollection.fromFeatures(new Feature[]{
pointPolygon, pointLineString, pointFeature
});
GeoJsonSource geoJsonSource = new GeoJsonSource("source-id", featureCollection);
style.addSource(geoJsonSource);
LineLayer lineLayer = new LineLayer("line-layer-id", "source-id");
lineLayer.setProperties(
PropertyFactory.lineColor(Color.BLUE)
);
style.addLayer(lineLayer);
}
});
I am currently developing android map using mapbox sdk, and I want to add multiple markers when user click on one button. and I type below in my onStyleLoaded but it's not showing anything
List<Feature> symbolLayerIconFeatureList = new ArrayList<>();
symbolLayerIconFeatureList.add(Feature.fromGeometry(
Point.fromLngLat(31.995560, 34.767070)));
symbolLayerIconFeatureList.add(Feature.fromGeometry(
Point.fromLngLat(31.995979, 34.744110)));
symbolLayerIconFeatureList.add(Feature.fromGeometry(
Point.fromLngLat(31.995010, 34.767380)));
style.addImage("charge-icon-id", BitmapFactory.decodeResource(
MapboxNavigationActivity.this.getResources(), R.drawable.map_marker_dark));
style.addSource(new GeoJsonSource("charge-source-id",
FeatureCollection.fromFeatures(symbolLayerIconFeatureList)));
SymbolLayer destinationSymbolLayer = new SymbolLayer("charge-layer-id", "charge-source-id");
destinationSymbolLayer.withProperties(iconImage("charge-icon-id"),
iconAllowOverlap(true),
iconIgnorePlacement(true)
);
style.addLayer(destinationSymbolLayer);
May I ask what are the problem?
It's a bit tough to say without some more context/information, but I'm guessing that the issue is related to the order in which you're adding the source, layer, and image. Take a look at this example: https://docs.mapbox.com/android/maps/examples/marker-symbol-layer/
You'll want to add the image, source, and layer before the style is loaded. You can then make additional adjustments/add data when the style is loaded using the onStyleLoaded listener.
Disclaimer: I work at Mapbox.
I am using map box in my android application. After initializing map box I want to add marker when on longClick on map box so in order according official site I added markerview dependency to application gradle:
dependencies {
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-markerview-v7:0.2.0'
}
And then I implements MapboxMap.OnMapLongClickListener and override onMapLongClick.
When mapview is ready I enable enableLocationComponent and create markerViewManager and set map long click listener.
mapView.getMapAsync(mapboxMap -> {
this.mapboxMap = mapboxMap;
mapboxMap.setStyle(Style.MAPBOX_STREETS, style -> {
createCustomAnimationView();
moveTo(home_longitude, home_latitude, home_zoom);
enableLocationComponent();
markerViewManager = new MarkerViewManager(mapView, mapboxMap);
mapboxMap.addOnMapLongClickListener(this);
createCustomAnimationView();
});
});
Finally in onMapLongClick overrided method I make a imageview and add to markerViewManager.
#Override
public boolean onMapLongClick(#NonNull LatLng point) {
ImageView imageView = new ImageView(requireContext());
imageView.setLayoutParams(new RelativeLayout.LayoutParams(
(int) Measurement.convertDpToPixel(32, requireContext()),
(int) Measurement.convertDpToPixel(32, requireContext())));
imageView.setImageResource(R.drawable.location_ic);
MarkerView markerView = new MarkerView(new LatLng(point.getLatitude(), point.getLongitude()), imageView);
markerViewManager.addMarker(markerView);
return false;
}
When I run application and do long click on screen:
First problem: location_ic appear on the top and left of the screen and after a second or more, icon placed in right place
Other problem:
When I move map, those markers stay fixed and not moved with map but after a second or more then placed in right place.
I hope I had explained clearly but if you are not understanding I uploaded a small video !!!
My video
after a few days and googleing, I finally decided to use SymbolManager to add marker on mapbox:
just add :
dependencies {
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v7:0.5.0'
}
to app gradle and then Initialize the plugin on onMapReady like below:
symbolManager = new SymbolManager(mapView, mapboxMap,style);
symbolManager.setIconAllowOverlap(true);
symbolManager.setTextAllowOverlap(true);
and use :
symbolManager.create(new SymbolOptions()
.withLatLng(point)
.withIconImage(IMAGE_MARKER_DEFAULT));
for helping look this page and this.
I hope it can be helpful.
I'm currently working with markers in mapbox too. But they are referred as "Symbols" in the latest versions.
To use them add the mapbox android sdk dependency to your project (tutorial from mapbox here ) and follow the other tutorial to use the symbol layer ( link here ).
If you have all your markers as a GeoJSON file, you can also add to a custom map that you would style on the mapbox website and then use in your app. ( other informations here )
I hope this can help you, this is my first attempt to answer at someone.
I had created a demo app to known about SKMaps, it worked good with adding annotations. However, now I have moved the code to actual project with the same requirements. Added annotations is not being displayed. I tried with both SKAnnotationView (custom view) and default Annotation type like SKAnnotation.SK_ANNOTATION_TYPE_RED and SKAnnotation.SK_ANNOTATION_TYPE_PURPLE. Nothing is being added to the map.
I have a custom view pager in the same screen, I removed the same and checked still didn't work. SKMapViewHolder is added dynamically.
Code snippet for adding SKMapViewHolder dynamically:
SKMapViewHolder mMapHolder = new SKMapViewHolder(OfflineMapScreen.this);
mMapHolder.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
RelativeLayout outerLayout = (RelativeLayout) findViewById(R.id.outer_layout);
outerLayout.addView(mMapHolder);
RelativeLayout.LayoutParams rlp = (android.widget.RelativeLayout.LayoutParams) mMapHolder.getLayoutParams();
rlp.addRule(RelativeLayout.BELOW, R.id.header);
mMapHolder.setLayoutParams(rlp);
mOSMMapView = mMapHolder.getMapSurfaceView();
mOSMMapView.setMapSurfaceListener(this);
mOSMMapView.getMapSettings().setFollowerMode(SKMapFollowerMode.NONE);
mOSMMapView.getMapSettings().setMapPanningEnabled(true);
mOSMMapView.getMapSettings().setInertiaPanningEnabled(true);
mOSMMapView.getMapSettings().setCompassShown(false);
mOSMMapView.getMapSettings().setCurrentPositionShown(false);
mOSMMapView.setZoomSmooth(14f, 500);
Anybody has the solution for this? Code snippet of adding annotations can be seen here: http://postimg.org/image/sdbwzej9z/
In the image you provided we have noticed that when setting the location you are reusing the same value for both latitude and longitude. Use something like:
annotationDrawable.setLocation(new SKCoordinate(Double.valueOf(aPlace.getLongitude()),Double.valueOf(aPlace.getLatitude())) ;
I am using the CCAnimation class for using animation with more than one CCSprite . What I want is :
" Just Remove the sprite after the animation complete "
If anybody work on this, Please Let me Know. What should I do for it.
I know the solution of pktangyue works but I want to add a new answer because this is deprecated in cocos2d-x V3.x Please read the final way to do this it's more easy
Node *nodeSprite =(Node*)layer->getChildByName("BFL_Ready_Label");
MoveTo* animation = MoveTo::create(1.0f,Point(Director::getInstance()->getWinSize().width/2,Director::getInstance()->getWinSize().height*1.5));
CallFunc* animationDone = CallFunc::create(bind(&Node::removeFromParent,nodeSprite));
Sequence* sequence = Sequence::create(animation,animation,NULL);
node->runAction(Sequence);
And like the previous answer using a Sprite.
MoveTo* animation = MoveTo::create(1.0f,Point(Director::getInstance()->getWinSize().width/2,Director::getInstance()->getWinSize().height*1.5));
CallFunc::create(bind(&Sprite::removeFromParent,m_sprite));
Sequence* sequence = Sequence::create(animation,animation,NULL);
m_sprite->runAction(sequence);
Using this the compiler will not tell that you're using deprecated methods. I hope this will useful.
I update this answer because there's a much easy way to do this
when you create a sequence just add the RemoveSelf::create RemoveSelf it's an action so you can add it to the sequence it will destroy the sprite or Node after the animation is complete.
Sequence* sequence = Sequence::create(animation,animation,RemoveSelf::Create(),NULL);
And that's the easy way to destroy the object after
the animation is completed this is very usefull in particles
Suppose m_action is your animation and m_sprite is you sprite node.
Then you can create a CCSequence action, with a CCCallFunc action in the final, like the following code:
CCSequence* seq = CCSequence::create(action,
CCCallFunc::create(m_sprite, callfunc_selector(CCSprite::removeFromParent),
NULL);
m_sprite->runAction(seq);
sprite_name->runAction(Sequence::create(ScaleTo::create(1, 0),RemoveSelf::create(), NULL));