I have my ARCGIS android app displaying a polyline shapefile file - a roading network in this case.
The shape file has a field that contains the name of the road "ROAD_NAME' - the question i have is how do i create a layer to have the road name automatically displayed?
cheers
B
I also tried to display labels on the map.
By my experiment, there are 2 ways. I realized it.One way is that draw those labels programmatically on the map. but it needs a lot of effort. I did it, it is not pretty. I think so.
public class LabelLayer extends GraphicsLayer {
...
private void showLabel(final FeatureLayer fly, final QueryParameters query,final String labelField) {
new Thread(new Runnable() {
#Override
public void run() {
fly.getFeatureTable().queryFeatures(query, new CallbackListener<FeatureResult>() {
#Override
public void onCallback(FeatureResult objects) {
Iterator<Object> fet=objects.iterator();
while (fet.hasNext()){
Feature f=(Feature) fet.next();
Geometry geom= f.getGeometry();
Point p=null;
switch (geom.getType()){
case POINT:p=(Point)geom;break;
case POLYLINE: Polyline polyline=(Polyline)geom;break;
case POLYGON: p= GeometryEngine.getLabelPointForPolygon((Polygon)geom,mapView.getSpatialReference());break;
default:break;
}
txtSymbol.setFontWeight(FontWeight.BOLD);
txtSymbol.setColor(Color.DKGRAY);
txtSymbol.setText(f.getAttributeValue(labelField).toString());
Graphic gr = new Graphic(p, txtSymbol);
LabelLayer.this.addGraphic(gr);
}
}
#Override
public void onError(Throwable throwable) {
}
});
}
}).start();
}
...
}
this class should be implemented in onDraw() method.
the second is that use the tpk of ArcGIS.
I think it would be better much.
Related
Im adding GeoJsonLayer to Google map on my application. This json contains coordinates for polygon and properties for each polygon. What I need is to get those properties when polygon is clicked. This is the code Im using to achieve that.
GeoJsonLayer jsonLayer = new GeoJsonLayer(mMap, geoJSON);
jsonLayer.addLayerToMap();
jsonLayer.setOnFeatureClickListener(new GeoJsonLayer.GeoJsonOnFeatureClickListener() {
#Override
public void onFeatureClick(final com.google.maps.android.data.Feature feature) {
mMap.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() {
#Override
public void onPolygonClick(Polygon polygon) {
for (Object s : feature.getProperties()) {
Log.d("getProperties", "getProperties = " + s.toString());
}
}
});
}
});
The problem is that it returns all properties. I want it to return properties only for the polygon I clicked.
Also its possible to draw polygons with user input. When I click on those polygons it triggers onPolygonClick() inside jsonLayer.setOnFeatureClickListener(). How to check if clicked polygon is from jsonLayer?
smart people :)!
Story: I have many layers what I have added to google maps in android. I am adding them by iterating - creating new GeoJsonLayer and calling method addLayerToMap(). I have created setOnFeatureClickListener on last GeoJsonLayer (Maybe here is the problem).
Problem: When I click on feature (LineString, Polygon) I receive information only about last Layer - polygon. Then I added mMap.setOnPolylineClickListener(), then click listener is going into correct methods - for LineString in PolyLineClick... etc, but here again is problem - how can I get information from Polyline about LineString properties, what I added to geoJson?
Question: What is the best approach to add layers to map , so I can manage click events and show LineString or Polygon properties for user?
Code example:
geoJsonLayer.setOnFeatureClickListener(new GeoJsonLayer.GeoJsonOnFeatureClickListener() {
#Override
public void onFeatureClick(Feature feature) {
mMap.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() {
#Override
public void onPolylineClick(Polyline polyline) {
//TODO show LineString properties
//Comes here when LineString clicked
}
});
mMap.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() {
#Override
public void onPolygonClick(Polygon polygon) {
//TODO show Polygon properties
//Comes here when Polygon clicked
}
});
}
Found solution - added all layers into 1 layer and everything works fine.
Am adding markers in my app on GoogleMaps,my markers allways are on streets.For example I have moore than 2 markers on map, I need to draw optimal route between them depending on streets.Is there any service to help me, or I need to create my own algorithm? Until now I worked a little with Google Elevation API and Google Direction API, but now I need Google Roads API, to find optimal roads between points? It must be something simmilar to my needs.
Consider using following library: https://github.com/akexorcist/Android-GoogleDirectionLibrary
GoogleDirection.withServerKey("YOUR_SERVER_API_KEY")
.from(new LatLng(37.7681994, -122.444538))
.to(new LatLng(37.7749003,-122.4034934))
.avoid(AvoidType.FERRIES)
.avoid(AvoidType.HIGHWAYS)
.execute(new DirectionCallback() {
#Override
public void onDirectionSuccess(Direction direction, String rawBody) {
if(direction.isOK()) {
// Do something
} else {
// Do something
}
}
#Override
public void onDirectionFailure(Throwable t) {
// Do something
}
});
Gradle
compile 'com.akexorcist:googledirectionlibrary:1.0.5'
I am working on iOS/Android map application.
To find a path between two locations in iOS, I am using MKDirectionsRequest.
How do I do it in Android?
I found Directions API, which is a Web service. So that I will have to send HTTP requests.
Isn't there any Java interface to calculate directions in Android?
To set this as an answer.
You can use Android-GoogleDirectionLibrary
As such:
GoogleDirection.withServerKey("YOUR_SERVER_API_KEY")
.from(new LatLng(37.7681994, -122.444538))
.to(new LatLng(37.7749003,-122.4034934))
.avoid(AvoidType.FERRIES)
.avoid(AvoidType.HIGHWAYS)
.execute(new DirectionCallback() {
#Override
public void onDirectionSuccess(Direction direction, String rawBody) {
if(direction.isOK()) {
// Do something
} else {
// Do something
}
}
#Override
public void onDirectionFailure(Throwable t) {
// Do something
}
});
I have one problem.
My goal is to load custom image of company and show it instead default marker icon.
But I have faced with the problem.
Icons are shown only if I close and open activity again.
Here is my code for adding markers to the map.
private void addMarkerToTheMap(GoogleMapInfoBundle infoBundle) {
if (infoBundle.placeMarker) {
LatLng latLng = new LatLng(infoBundle.company.getLatitude(), infoBundle.firm.getLongitude());
MarkerOptions markerOptions = new MarkerOptions()
.title(infoBundle.company.getName())
.snippet(infoBundle.company.getAddress())
.position(latLng);
Marker marker = mGoogleMap.addMarker(markerOptions);
try {
Picasso.with(this).load(NetworkUtils.getUrlOfScaledImage(infoBundle.company.getLogo(), DEFAULT_ICON_SCALE_PERCENTAGE)).into(new PicassoMarker(marker));
} catch (IllegalArgumentException ignore) {
// Do nothing
}
}
And PicassoMarker
public class PicassoMarker implements Target {
Marker mMarker;
public PicassoMarker(Marker marker) {
mMarker = marker;
}
#Override
public int hashCode() {
return mMarker.hashCode();
}
#Override
public boolean equals(Object o) {
if (o instanceof PicassoMarker) {
Marker marker = ((PicassoMarker) o).mMarker;
return mMarker.equals(marker);
} else {
return false;
}
}
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
}
In this case it displays default icon .
I have tried to make it in another way like this
MarkerOptions markerOptions = new MarkerOptions()
.title(infoBundle.company.getName())
.snippet(infoBundle.company.getAddress())
.position(latLng);
try {
Picasso.with(this).load(NetworkUtils.getUrlOfScaledImage(infoBundle.company.getLogo(), DEFAULT_ICON_SCALE_PERCENTAGE)).into(new PicassoMarker(mGoogleMap, markerOptions));
} catch (IllegalArgumentException ignore) {
// Do nothing
}
And add marker to the map in callback after image has been downloaded.
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
mMarkerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
mGoogleMap.addMarker(mMarkerOptions);
}
It doesn't show any marker in this case.
But in both cases if I close Activity and open it again everything will be displayed correctly with icons as it should.
I have no idea what can cause such problem. It seems GoogleMap caches icon image or something else.
I have a little experience working with GoogleMaps API, maybe I am missing something.
Hope someone can help.
Thanks.
The problem was not in GoogleMap or SupportMapFragment it was in Picasso, not exactly in Picasso but in my flow.
The thing you should always remember using custom Target classes is that internally Picasso uses WeakReference for storing Target objects, so if you will just create new Target directly inside Picasso call it will be destroyed by garbage collector.
Picasso provides Callback class, so you can create anonymous class instead and that you class will hold the reference.
But one thing that is I am missing Callback class that provides Bitmap in response like Target(but targets are mostly used by custom views).
So I have found such solution, it ugly, but here it is.
I have created special list for storing target objects, not to be garbaged.
Marker marker = mGoogleMap.addMarker(markerOptions);
mMarkerCompanyMap.put(marker, infoBundle.firm);
try {
PicassoMarkerTarget markerTarget = new PicassoMarkerTarget(marker, mImageLoadingCallback);
mPicassoMarkerTargetList.add(markerTarget);
Picasso.with(this)
.load(NetworkUtils.getUrlOfScaledImage(infoBundle.firm.getLogo(), DEFAULT_ICON_SCALE_PERCENTAGE))
.into(markerTarget);
} catch (IllegalArgumentException ignore) {
// Do nothing
}
I am passing mImageLoadingCallback for having callback back to the activity from Target
And it looks like.
private Callback mImageLoadingCallback = new Callback() {
#Override
public void onSuccess() {
Logger.logError("IMAGE LOADED IN CALLBACK " + mPendingImagesCount);
if (mPendingImagesCount <= 0) {
mPicassoMarkerTargetList.clear();
} else {
mPendingImagesCount--;
}
}
#Override
public void onError() {
// You may start laughing, but just for the sake of not duplicating code
onSuccess();
}
};
This callback can be used for other purposes, but now only for clear array.
And of course PicassoMarkerTarget
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
mDownloadListenerCallback.onSuccess();
Logger.logError("IMAGE LOADED IN PICASSO MARKER TARGET");
}
This is ugly solution but maybe this callback can be helpful in the future.
Please, if you have idea how to make solution better - please share it.
Thanks.