Skip to content
This repository has been archived by the owner on Jan 26, 2023. It is now read-only.

Create Buffer using current location #521

Open
wencelaus opened this issue Jul 26, 2018 · 6 comments
Open

Create Buffer using current location #521

wencelaus opened this issue Jul 26, 2018 · 6 comments

Comments

@wencelaus
Copy link

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.

@eric906
Copy link

eric906 commented Jul 27, 2018

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?

@wencelaus
Copy link
Author

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();
            }


        }
    });

**

@eric906
Copy link

eric906 commented Jul 30, 2018

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();

@wencelaus
Copy link
Author

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();
            }
        }
    });**

screenshot_20180802-115812 1

@eric906
Copy link

eric906 commented Aug 2, 2018

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?

@wencelaus
Copy link
Author

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants