Draw a path on maps along the path of a finger on the device’s screen

1) I want to draw the trajectory of movement on the Google map in accordance with the following points of touching the fingers in the map area. 2) and get the selected area from the map, which is inside the path.

Anyone has an idea how to achieve it.

For reference, I want to do something similar: -

enter image description here

+6
source share
1 answer

I implemented the same for one of my hopes applications that will help you, I did it with a poly line and a polygon.

activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.SupportMapFragment" /> <View android:id="@+id/drawer_view" android:layout_width="wrap_content" android:layout_height="match_parent" /> <Button android:id="@+id/draw_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="drawZone" android:padding="10dp" android:text="Draw" /> </RelativeLayout> </RelativeLayout> 

The next class will cover the full code for drawing a user area in a Google map v2

 MainActivity.java import java.util.ArrayList; import android.graphics.Color; import android.graphics.Point; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.PolygonOptions; import com.google.android.gms.maps.model.PolylineOptions; public class MainActivity extends FragmentActivity implements OnTouchListener { private static final String TAG = "polygon"; private GoogleMap mGoogleMap; private View mMapShelterView; private GestureDetector mGestureDetector; private ArrayList<LatLng> mLatlngs = new ArrayList<LatLng>(); private PolylineOptions mPolylineOptions; private PolygonOptions mPolygonOptions; // flag to differentiate whether user is touching to draw or not private boolean mDrawFinished = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMapShelterView = (View) findViewById(R.id.drawer_view); mGestureDetector = new GestureDetector(this, new GestureListener()); mMapShelterView.setOnTouchListener(this); initilizeMap(); } private final class GestureListener extends SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } } /** * Ontouch event will draw poly line along the touch points * */ @Override public boolean onTouch(View v, MotionEvent event) { int X1 = (int) event.getX(); int Y1 = (int) event.getY(); Point point = new Point(); point.x = X1; point.y = Y1; LatLng firstGeoPoint = mGoogleMap.getProjection().fromScreenLocation( point); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: if (mDrawFinished) { X1 = (int) event.getX(); Y1 = (int) event.getY(); point = new Point(); point.x = X1; point.y = Y1; LatLng geoPoint = mGoogleMap.getProjection() .fromScreenLocation(point); mLatlngs.add(geoPoint); mPolylineOptions = new PolylineOptions(); mPolylineOptions.color(Color.RED); mPolylineOptions.width(3); mPolylineOptions.addAll(mLatlngs); mGoogleMap.addPolyline(mPolylineOptions); } break; case MotionEvent.ACTION_UP: Log.d(TAG, "Poinnts array size " + mLatlngs.size()); mLatlngs.add(firstGeoPoint); mGoogleMap.clear(); mPolylineOptions = null; mMapShelterView.setVisibility(View.GONE); mGoogleMap.getUiSettings().setZoomGesturesEnabled(true); mGoogleMap.getUiSettings().setAllGesturesEnabled(true); mPolygonOptions = new PolygonOptions(); mPolygonOptions.fillColor(Color.GRAY); mPolygonOptions.strokeColor(Color.RED); mPolygonOptions.strokeWidth(5); mPolygonOptions.addAll(mLatlngs); mGoogleMap.addPolygon(mPolygonOptions); mDrawFinished = false; break; } return mGestureDetector.onTouchEvent(event); } /** * Setting up map * */ private void initilizeMap() { int status = GooglePlayServicesUtil .isGooglePlayServicesAvailable(getApplicationContext()); if (status == ConnectionResult.SUCCESS) { if (mGoogleMap == null) { mGoogleMap = ((SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map)).getMap(); mGoogleMap.setMyLocationEnabled(true); } } else if (GooglePlayServicesUtil.isUserRecoverableError(status)) { // showErrorDialog(status); } else { Toast.makeText(this, "No Support for Google Play Service", Toast.LENGTH_LONG).show(); } } /** * Method gets called on tap of draw button, It prepares the screen to draw * the polygon * * @param view */ public void drawZone(View view) { mGoogleMap.clear(); mLatlngs.clear(); mPolylineOptions = null; mPolygonOptions = null; mDrawFinished = true; mMapShelterView.setVisibility(View.VISIBLE); mGoogleMap.getUiSettings().setScrollGesturesEnabled(false); } } 

Hope the above code is good enough to draw a custom area on v2 map. To determine whether a particular point is inside the user region or not, we can use the fragment below.

 public synchronized boolean Contains(Location location) { boolean isInside = false; if (mLatlngs.size() > 0) { LatLng lastPoint = mLatlngs.get(mLatlngs.size() - 1); double x = location.getLongitude(); for (LatLng point : mLatlngs) { double x1 = lastPoint.longitude; double x2 = point.longitude; double dx = x2 - x1; if (Math.abs(dx) > 180.0) { if (x > 0) { while (x1 < 0) x1 += 360; while (x2 < 0) x2 += 360; } else { while (x1 > 0) x1 -= 360; while (x2 > 0) x2 -= 360; } dx = x2 - x1; } if ((x1 <= x && x2 > x) || (x1 >= x && x2 < x)) { double grad = (point.latitude - lastPoint.latitude) / dx; double intersectAtLat = lastPoint.latitude + ((x - x1) * grad); if (intersectAtLat > location.getLatitude()) isInside = !isInside; } lastPoint = point; } } return isInside; } 

You can pass the location parameter to the method, it will return whether this location will be inside the user region or not.

manifest.xml

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.testdraw" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <permission android:name=".permission.MAPS_RECEIVE" android:protectionLevel="signature" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="in.wptrafficanalyzer.locationingooglemapv2.permission.MAPS_RECEIVE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyDkYvXC1pmSiBrt5Ja3F6gk-wBwIMuDNwo" /> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> </application> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> </manifest> 
+5
source

Source: https://habr.com/ru/post/977324/


All Articles