arcgis-runtime-samples-android
arcgis-runtime-samples-android copied to clipboard
Create Buffer using current location
Hello, I would like to create a buffer from my my current location point without having to touch the MapView.
The code below works but when a point is touched on the MapView. I'd rather like to get a point of the locationDisplay loaded i.e (loc = locationDisplay.getMapLocation();) and use it to create a buffer. _
hospitals_MapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, hospitals_MapView) { @Override public boolean onSingleTapConfirmed(MotionEvent motionEvent) { // get the point that was clicked and convert it to a point in the map
android.graphics.Point clickLocation = new android.graphics.Point(Math.round(motionEvent.getX()), Math.round(motionEvent.getY())); Toast.makeText(Hospitals_Activity.this, ""+clickLocation, Toast.LENGTH_LONG).show(); //graphicsOverlay.clearSelection(); Point mapPoint = mMapView.screenToLocation(clickLocation); // only draw a buffer if a value was entered if (!bufferInput.toString().isEmpty()) { Polygon bufferGeometry = GeometryEngine .buffer(mapPoint, miles.convertTo(meters, Double.valueOf(bufferInput.toString()))); // show the buffered region as a green graphic Graphic bufferGraphic = new Graphic(bufferGeometry, fillSymbol); graphicsOverlay.getGraphics().add(bufferGraphic); // show a red marker where clicked Graphic markerGraphic = new Graphic(mapPoint, new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE,0xFFFF0000, 5)); //graphicsOverlay.getGraphics().add(markerGraphic); } else { Toast.makeText(Hospitals_Activity.this, "Please enter a buffer distance first.", Toast.LENGTH_LONG).show(); } return true; } });
_
When I try to use the point extracted from locationDisplay and call it from a Button Action nothing happens. I get no error but I also get no result. Kindly help. Thanks.
You can get the geometry from locationDisplay, then use getMapLocation to get the point to create the buffer with. This should work, but are you not seeing the results? Are you using an emulator?
Hi Eric, I am actually using my Android Device for testing. I did get good results with the .setonTouchListener but my major challenge is now getting a point of the current location and showing a buffer around it or even just showing the buffer on opening the activity. Well here's the code I'm trying to use. Kindly advise if I'm doing it wrongly and what I should correct.
**>
ImageButton go = (findViewById(R.id.my_location_button));
go.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (canGetLocation() == true) { locationDisplay = hospitals_MapView.getLocationDisplay(); locationDisplay.startAsync(); locationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.NAVIGATION); loc = locationDisplay.getMapLocation(); } else { showSettingsAlert(); } //Point wgs84Point = (Point) GeometryEngine.project(loc, SpatialReferences.getWgs84());
// // wgs84Point = new Point(Math.round(loc.getX()),Math.round(loc.getY()));
double x = loc.getX(); int intx = (int)x; double y = loc.getY(); int inty = (int)y; //Toast.makeText(getApplicationContext(),"x : "+intx+" y : "+inty,Toast.LENGTH_LONG).show(); android.graphics.Point locationPoint = new android.graphics.Point(Math.round(intx),Math.round(inty)); //Toast.makeText(getApplicationContext(),locationPoint.toString(),Toast.LENGTH_LONG); final Integer bufferInput = 1; final LinearUnit miles = new LinearUnit(LinearUnitId.MILES); final LinearUnit meters = new LinearUnit(LinearUnitId.METERS); final SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, 0x8800FF00, new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, 0xFF057e15, 5)); GraphicsOverlay graphicsOverlay = new GraphicsOverlay(); Polygon bufferGeometry = GeometryEngine.buffer(loc, miles.convertTo(meters, Double.valueOf(bufferInput.toString()))); // show the buffered region as a green graphic Graphic bufferGraphic = new Graphic(bufferGeometry, fillSymbol); graphicsOverlay.getGraphics().add(bufferGraphic); // show a red marker where clicked Graphic markerGraphic = new Graphic(loc, new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE,0xFFFF0000, 15)); graphicsOverlay.getGraphics().add(markerGraphic); //Point mapPoint = hospitals_MapView.screenToLocation(locationPoint); // only draw a buffer if a value was entered if (!bufferInput.toString().isEmpty()) { } else { Toast.makeText(Hospitals_Activity.this, "Please enter a buffer distance first.", Toast.LENGTH_LONG).show(); } } });
**
Wait for the LocationDisplay to start before trying to use it.
For example, here is my code that seems to work for me. I'm listening for when the location display has started, then I'll call my bufferLocation method:
// get the MapView's LocationDisplay
mLocationDisplay = mMapView.getLocationDisplay();
// Listen to changes in the status of the location data source.
mLocationDisplay.addDataSourceStatusChangedListener(new LocationDisplay.DataSourceStatusChangedListener() {
@Override
public void onStatusChanged(LocationDisplay.DataSourceStatusChangedEvent dataSourceStatusChangedEvent) {
// If LocationDisplay started OK, then continue.
if (dataSourceStatusChangedEvent.isStarted())
bufferLocation();
.....
}
}
});
mLocationDisplay.startAsync();
Hello Eric, Thanks very much for at least giving me a first break through. I bear good news and bad news. The good news is clicking a button to load buffer around a point has finally worked. This will come in handy in case I completely cannot get the buffer when the Map Loads.
The bad news is .addDataSourceStatusChangedListener seems not to work efficiently. The Content in the inner class can somehow not be accessed when the coordinates have been loaded. See image below where I toast the result. Therefore, I can still not load the Buffer when the location immediately loads without having to initiate the action by a button click.
Here is the code.
**> locationDisplay = health_lab_mapview.getLocationDisplay();
locationDisplay.getMapLocation(); locationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.NAVIGATION); Toast.makeText(getApplicationContext(),"Location Loaded"+locationDisplay.getMapLocation(),Toast.LENGTH_LONG).show(); //This is outside the class and gives the result [0.00000,0.00000,0.00000,NaN] locationDisplay.addDataSourceStatusChangedListener(new LocationDisplay.DataSourceStatusChangedListener() { @Override public void onStatusChanged(LocationDisplay.DataSourceStatusChangedEvent dataSourceStatusChangedEvent) { if(dataSourceStatusChangedEvent.isStarted()&&locationDisplay.getMapLocation()!=null) { Toast.makeText(getApplicationContext(),"Data Source Location Loaded"+locationDisplay.getMapLocation(),Toast.LENGTH_LONG).show(); //This is inside the class and gives the result [0.00000,0.00000,0.00000,NaN] } else { Toast.makeText(getApplicationContext(),"Please wait for the Location to load",Toast.LENGTH_LONG).show(); } } });**
Thanks for sharing.
The only difference is, in my code that works, simply check fo "isStarted()", instead of "isStarted()&&locationDisplay.getMapLocation()!=null)"
What happens when you omit "&&locationDisplay.getMapLocation()!=null)" from that check?
When I omit "&&locationDisplay.getMapLocation()!=null)" I still get the result above. Is there a way I can get the point when it already has coordinates say perhaps delay it for 2 or 3 seconds? I feel like the problem is when I call isStarted() immediately the MapView opens, I get the Point when the co-ordinates are still 0.000000.