如何在Android的谷歌地图V2中绘制手绘多边形?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20901141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:40:02  来源:igfitidea点击:

How to draw free hand polygon in Google map V2 in Android?

androidgoogle-mapsoverlaydrawpolygon

提问by Chintan Khetiya

I want to draw a Free Hand Polygon on the Map in Google Map V2.

我想画一个Free Hand Polygon on the Map in Google Map V2

This task was possible with OverlayMap V1 but Google Map has removed that class from V2. (Per this Google Map V2 has Remove Overlay Class).

OverlayMap V1可以完成此任务,但 Google Map 已从 V2 中删除了该类。(根据这个Google Map V2 有 Remove Overlay Class)。

Good Example for Google Map V1 to draw free style polygon.

谷歌地图 V1 绘制自由样式多边形的好例子。

In Map V2, we can draw a polygon programmatically with the help of Google Official Docbut what should a user do? I have found Unclear answer for Map V2

在 Map V2 中,我们可以借助Google Official Doc以编程方式绘制多边形,但是用户应该怎么做?我发现Map V2 的答案不明确

I started with simple Google Map & draw polygon to do this programmatically & it is working properly but now I am looking for how a user can draw? I don't want to draw based on the marker on the polygon.

我从简单的谷歌地图开始,并以编程方式绘制多边形来执行此操作,并且它工作正常,但现在我正在寻找用户如何绘制?我不想根据多边形上的标记进行绘制。

// Instantiates a new Polygon object and adds points to define a rectangle
PolygonOptions rectOptions = new PolygonOptions()
              .add(new LatLng(37.35, -122.0),
                   new LatLng(37.45, -122.0),
                   new LatLng(37.45, -122.2),
                   new LatLng(37.35, -122.2),
                   new LatLng(37.35, -122.0));

// Get back the mutable Polygon
Polygon polygon = myMap.addPolygon(rectOptions);

I have done lots of Research and Development on this topic but didn't get a perfect way to implement such a thing in Map V2.

我在这个主题上做了很多研究和开发,但没有找到在 Map V2 中实现这种事情的完美方法。

Some Questions

一些问题

  • How to draw freestyle polygon in Map V2 (as we can do with Map V1)?
  • Is there any trick or alternative to achieve this? If yes how?
  • Can we get a touch event on the map & draw polygon?
  • Is it feasible in Map V2?
  • Is it possible with a touch event which returns array of lat-long?
  • How can I get Lat-long based on screen coordinates on setOnDragListener?
  • 如何在 Map V2 中绘制自由式多边形(就像我们在 Map V1 中所做的那样)?
  • 有什么技巧或替代方法可以实现这一目标吗?如果是如何?
  • 我们可以在地图上获得触摸事件并绘制多边形吗?
  • 在 Map V2 中可行吗?
  • 是否可以使用返回经纬度数组的触摸事件?
  • 如何根据屏幕坐标获得 Lat-long setOnDragListener

Each new version has something extra compared to the older one so I am expecting that I can achieve the same thing in Map v2 also.

与旧版本相比,每个新版本都有一些额外的东西,所以我希望我也可以在 Map v2 中实现相同的功能。

I am not asking to give me some sample code or post your code, just some proper direction & documentation.

我不是要给我一些示例代码或发布您的代码,只是一些正确的方向和文档。

I have provided all documents and evidence I found during the Research and Development.

我已经提供了我在研究和开发过程中找到的所有文件和证据。

回答by Chintan Khetiya

After spending a whole day in Rnd and testing some alternatives I have found a solution. Actually I have found two alternatives for the same issue but I would like to suggest the using of Alternative 2because that is really very easy compared to Alternative 1.

在 Rnd 度过一整天并测试了一些替代方案后,我找到了解决方案。实际上,我为同一问题找到了两种替代方案,但我想建议使用替代方案 2,因为与替代方案 1相比,这确实非常容易。

Actually I have found Alternative 1with the help of TheLittleNaruto, AndroidHackerand some other developers & Alternative 2with the help of Khanso thanks to all.

其实我已经找到替代1的帮助下TheLittleNarutoAndroidHacker和其他一些开发商和方案2的帮助下可汗所以感谢所有。

Alternative 1

备选方案 1

How to Draw Free style polygon in Map V2 (as we can do with Map V1) ? Is it feasible in Map V2 ?

如何在 Map V2 中绘制自由样式的多边形(就像我们在 Map V1 中所做的那样)?在 Map V2 中可行吗?

Yes, that is feasible but you can't get directly OnTouch()& OnDraw()on the map. So we must have to think some other way to achieve this.

是的,这是可行的,但您无法直接在地图上获得OnTouch()& OnDraw()。因此,我们必须考虑其他方式来实现这一目标。

Is there any trick or alternative way to achieve this thing , if yes how ?

有没有什么技巧或替代方法来实现这件事,如果是,如何?

Yes, Google Map V2 doesn't support OnTouch()or OnDraw()on a Map using class="com.google.android.gms.maps.SupportMapFragment"so we have to plan for a custom Fragment.

是的,Google Map V2 不支持OnTouch()OnDraw()在地图上使用,class="com.google.android.gms.maps.SupportMapFragment"因此我们必须计划自定义 Fragment。

Is it possible to return array of lat-long with touch event ?

是否可以通过触摸事件返回经纬度数组?

Yes, if we create any custom map fragment and use it we can get that Touchor Dragevent over the map.

是的,如果我们创建任何自定义地图片段并使用它,我们可以在地图上获得TouchDrag事件。

How can I get Lat-long base on screen coordinates on setOnDragListener ?

如何根据 setOnDragListener 上的屏幕坐标获得经纬度?

setOnDragListenerwill return screen coordinates (x,y). Now for that, there are some techniques to convert (x,y)to LatLngand they include Projectionalong with Point& LatLng.

setOnDragListener将返回屏幕坐标(x,y)。现在,有一些技术可以将(x,y)转换为LatLng,它们包括ProjectionPoint& LatLng

customMapFragment.setOnDragListener(new MapWrapperLayout.OnDragListener() {@Override
    public void onDrag(MotionEvent motionEvent) {
        Log.i("ON_DRAG", "X:" + String.valueOf(motionEvent.getX()));
        Log.i("ON_DRAG", "Y:" + String.valueOf(motionEvent.getY()));

        float x = motionEvent.getX(); // get screen x position or coordinate 
        float y = motionEvent.getY();  // get screen y position or coordinate 

        int x_co = Integer.parseInt(String.valueOf(Math.round(x))); // casting float to int 
        int y_co = Integer.parseInt(String.valueOf(Math.round(y))); // casting float to int 

        projection = mMap.getProjection(); // Will convert your x,y to LatLng
        Point x_y_points = new Point(x_co, y_co);// accept int x,y value
        LatLng latLng = mMap.getProjection().fromScreenLocation(x_y_points); // convert x,y to LatLng
        latitude = latLng.latitude; // your latitude 
        longitude = latLng.longitude; // your longitude 

        Log.i("ON_DRAG", "lat:" + latitude);
        Log.i("ON_DRAG", "long:" + longitude);

        // Handle motion event:
    }
});

How does it work ?

它是如何工作的 ?

As I have already mentioned before, we have to create a custom root viewand using that we can get Touchor DragEvents over the map.

正如我之前已经提到的,我们必须创建一个自定义的根视图,并使用它我们可以在地图上获得触摸拖动事件。

Step 1: We Create MySupportMapFragment extends SupportMapFragmentand we will use that as our .xml file

第 1 步:我们创建MySupportMapFragment extends SupportMapFragment,我们将使用它作为我们的 .xml 文件

 <fragment
        android:id="@+id/map"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        class="pkg_name.MySupportMapFragment" /> 

Step 2: Create a MapWrapperLayout extends FrameLayoutso that we can set a Touch or Drag listenerinside and embed its view with map view. So, we need one Interface which we will use in Root_Map.java

第 2 步:创建一个MapWrapperLayout extends FrameLayout以便我们可以在其中设置一个Touch 或 Drag 侦听器并将其视图嵌入到地图视图中。所以,我们需要一个我们将在 Root_Map.java 中使用的接口

MySupportMapFragment.Java

MySupportMapFragment.Java

public class MySupportMapFragment extends SupportMapFragment {
    public View mOriginalContentView;
    public MapWrapperLayout mMapWrapperLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {

        mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState);
        mMapWrapperLayout = new MapWrapperLayout(getActivity());
        mMapWrapperLayout.addView(mOriginalContentView);
        return mMapWrapperLayout;
    }

    @Override
    public View getView() {
        return mOriginalContentView;
    }

    public void setOnDragListener(MapWrapperLayout.OnDragListener onDragListener) {
        mMapWrapperLayout.setOnDragListener(onDragListener);
    }
}

MapWrapperLayout.java

MapWrapperLayout.java

    public class MapWrapperLayout extends FrameLayout {
     private OnDragListener mOnDragListener;

     public MapWrapperLayout(Context context) {
         super(context);
     }

     public interface OnDragListener {
         public void onDrag(MotionEvent motionEvent);
     }

     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         if (mOnDragListener != null) {
             mOnDragListener.onDrag(ev);
         }
         return super.dispatchTouchEvent(ev);
     }

     public void setOnDragListener(OnDragListener mOnDragListener) {
         this.mOnDragListener = mOnDragListener;
     }

 }

Root_Map.Java

Root_Map.Java

public class Root_Map extends FragmentActivity {

    private GoogleMap mMap;
    public static boolean mMapIsTouched = false;
    MySupportMapFragment customMapFragment;
    Projection projection;
    public double latitude;
    public double longitude;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.root_map);
        MySupportMapFragment customMapFragment = ((MySupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
        mMap = customMapFragment.getMap();

        customMapFragment.setOnDragListener(new MapWrapperLayout.OnDragListener() {               @Override
            public void onDrag(MotionEvent motionEvent) {
                Log.i("ON_DRAG", "X:" + String.valueOf(motionEvent.getX()));
                Log.i("ON_DRAG", "Y:" + String.valueOf(motionEvent.getY()));

                float x = motionEvent.getX();
                float y = motionEvent.getY();

                int x_co = Integer.parseInt(String.valueOf(Math.round(x)));
                int y_co = Integer.parseInt(String.valueOf(Math.round(y)));

                projection = mMap.getProjection();
                Point x_y_points = new Point(x_co, y_co);
                LatLng latLng = mMap.getProjection().fromScreenLocation(x_y_points);
                latitude = latLng.latitude;
                longitude = latLng.longitude;

                Log.i("ON_DRAG", "lat:" + latitude);
                Log.i("ON_DRAG", "long:" + longitude);

                // Handle motion event:
            }
        });
    }}

Reference Link1, Link2

参考链接1链路2

Up to here I am able to get LatLongbased on X,Y screen coordinates. Now I just have to store it in Array. That array will be used for drawing on the map and finally it will look like a free shape polygon.

到目前为止,我可以根据X,Y 屏幕坐标获得LatLong。现在我只需要将它存储在Array 中。该数组将用于在地图上绘制,最后它看起来像一个自由形状的多边形。

enter image description here

在此处输入图片说明

I hope this will definitely help you.

我希望这肯定会帮助你。

Update:

更新:

Alternative 2

备选方案 2

As we know, Frame layoutis a transparent layout so I have achieved this using Frame Layout. In this case, there is no need to create a custom fragment. I have just used Frame Layoutas root layout. So basically I will get Touch Eventsin the root layout and that will return screen coordinates, as we got in custom fragment previously.

众所周知,Frame 布局是一种透明布局,所以我使用 Frame Layout 实现了这一点。在这种情况下,无需创建自定义片段。我刚刚使用框架布局作为根布局。所以基本上我会在根布局中获得触摸事件,这将返回屏幕坐标,正如我们之前在自定义片段中获得的那样。

Now, I have created a Button inside the "Free Draw". So when you click on that you can move your fingers on the map and draw a free hand polygon and that will disable your map being movable on screen. When you re-click the same button, the screen goes in ideal mode.

现在,我在“自由抽奖”中创建了一个按钮。因此,当您单击它时,您可以在地图上移动手指并绘制一个手绘多边形,这将使您的地图无法在屏幕上移动。当您重新单击同一按钮时,屏幕将进入理想模式。

root_map.xml

root_map.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <fragment
        android:id="@+id/map"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        class="com.google.android.gms.maps.SupportMapFragment" />

    <FrameLayout
        android:id="@+id/fram_map"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <Button
            android:id="@+id/btn_draw_State"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Free Draw" />
    </FrameLayout>

</FrameLayout>

Root_Map.java

Root_Map.java

FrameLayout fram_map = (FrameLayout) findViewById(R.id.fram_map);
Button btn_draw_State = (Button) findViewById(R.id.btn_draw_State);
Boolean Is_MAP_Moveable = false; // to detect map is movable 

// Button will change Map movable state

// 按钮将改变地图可移动状态

btn_draw_State.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Is_MAP_Moveable = !Is_MAP_Moveable;
    }
});

Touch Click of Frame Layout and with the help of the do some task

触摸单击框架布局并在执行某些任务的帮助下

fram_map.setOnTouchListener(new View.OnTouchListener() {     @Override
    public boolean onTouch(View v, MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        int x_co = Math.round(x);
        int y_co = Math.round(y);

        projection = mMap.getProjection();
        Point x_y_points = new Point(x_co, y_co);

        LatLng latLng = mMap.getProjection().fromScreenLocation(x_y_points);
        latitude = latLng.latitude;

        longitude = latLng.longitude;

        int eventaction = event.getAction();
        switch (eventaction) {
            case MotionEvent.ACTION_DOWN:
                // finger touches the screen
                val.add(new LatLng(latitude, longitude));

            case MotionEvent.ACTION_MOVE:
                // finger moves on the screen
                val.add(new LatLng(latitude, longitude));

            case MotionEvent.ACTION_UP:
                // finger leaves the screen
                Draw_Map();
                break;
        }

        return Is_MAP_Moveable;

    }
});

// Draw your map

// 绘制地图

public void Draw_Map() {
    rectOptions = new PolygonOptions();
    rectOptions.addAll(val);
    rectOptions.strokeColor(Color.BLUE);
    rectOptions.strokeWidth(7);
    rectOptions.fillColor(Color.CYAN);
    polygon = mMap.addPolygon(rectOptions);
}

Yet, now you have to maintain your list while you draw, so you have to clear your previous list data.

但是,现在您必须在绘制时维护您的列表,因此您必须清除以前的列表数据。

回答by AndroidHacker

Check this out .. I believe U are capable of showing Google Map v2

看看这个..我相信你有能力显示谷歌地图 v2

Check out "decodePoly" and "drawPath" method in AsyncTask

查看 AsyncTask 中的“decodePoly”和“drawPath”方法

Main Imphasis in "drawPath" ..

“drawPath”中的主要重点..

PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
for (int z = 0; z < list.size(); z++) {
    LatLng point = list.get(z);
    options.add(point);
}
line = myMap.addPolyline(options);

Complete class for your reference ..

完整的课程供您参考..

package com.example.androidhackergooglemap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class MainActivity extends FragmentActivity implements OnClickListener {

    private GoogleMap myMap;
    Polyline line;
    Context context;

    Location location;
    boolean check_provider_enabled = false;

    // Static LatLng
    LatLng startLatLng = new LatLng(30.707104, 76.690749);
    LatLng endLatLng = new LatLng(30.721419, 76.730017);

    public void onCreate(Bundle bd) {
        super.onCreate(bd);
        setContentView(R.layout.activity_main);
        context = MainActivity.this;

        // GoogleMap myMap
        myMap = ((SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map)).getMap();
        myMap.setMyLocationEnabled(true);
        myMap.moveCamera(CameraUpdateFactory.newLatLng(startLatLng));
        myMap.animateCamera(CameraUpdateFactory.zoomTo(12));

        LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
        boolean enabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);
        location = service.getLastKnownLocation(LocationManager.GPS_PROVIDER);

        // check if enabled and if not send user to the GSP settings
        // Better solution would be to display a dialog and suggesting to 
        // go to the settings
        if (!enabled) {
            /*Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);*/
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
            Toast.makeText(getApplicationContext(), "Enable GPS servcies to use this app.", Toast.LENGTH_LONG).show();
        } else {
            try {
                String urlTopass = makeURL(startLatLng.latitude,
                    startLatLng.longitude, endLatLng.latitude,
                    endLatLng.longitude);
                new connectAsyncTask(urlTopass).execute();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // Now auto clicking the button
        // btntemp.performClick();
    }


    private class connectAsyncTask extends AsyncTask < Void, Void, String > {
        private ProgressDialog progressDialog;
        String url;

        connectAsyncTask(String urlPass) {
            url = urlPass;
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            progressDialog = new ProgressDialog(context);
            progressDialog.setMessage("Fetching route, Please wait...");
            progressDialog.setIndeterminate(true);
            progressDialog.show();
        }

        @Override
        protected String doInBackground(Void...params) {
            JSONParser jParser = new JSONParser();
            String json = jParser.getJSONFromUrl(url);
            return json;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            progressDialog.hide();
            if (result != null) {
                drawPath(result);
            }
        }
    }

    public String makeURL(double sourcelat, double sourcelog, double destlat,
        double destlog) {
        StringBuilder urlString = new StringBuilder();
        urlString.append("http://maps.googleapis.com/maps/api/directions/json");
        urlString.append("?origin="); // from
        urlString.append(Double.toString(sourcelat));
        urlString.append(",");
        urlString.append(Double.toString(sourcelog));
        urlString.append("&destination="); // to
        urlString.append(Double.toString(destlat));
        urlString.append(",");
        urlString.append(Double.toString(destlog));
        urlString.append("&sensor=false&mode=driving&alternatives=true");
        return urlString.toString();
    }

    public class JSONParser {

        InputStream is = null;
        JSONObject jObj = null;
        String json = "";

        // constructor
        public JSONParser() {}

        public String getJSONFromUrl(String url) {

            // Making HTTP request
            try {
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                BufferedReader reader = new BufferedReader(
                    new InputStreamReader(is, "iso-8859-1"), 8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }

                json = sb.toString();
                is.close();
            } catch (Exception e) {
                Log.e("Buffer Error", "Error converting result " + e.toString());
            }
            return json;
        }
    }

    public void drawPath(String result) {
        if (line != null) {
            myMap.clear();
        }
        myMap.addMarker(new MarkerOptions().position(endLatLng).icon(
            BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
        myMap.addMarker(new MarkerOptions().position(startLatLng).icon(
            BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
        try {
            // Tranform the string into a json object
            final JSONObject json = new JSONObject(result);
            JSONArray routeArray = json.getJSONArray("routes");
            JSONObject routes = routeArray.getJSONObject(0);
            JSONObject overviewPolylines = routes
                .getJSONObject("overview_polyline");
            String encodedString = overviewPolylines.getString("points");
            List < LatLng > list = decodePoly(encodedString);

            PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
            for (int z = 0; z < list.size(); z++) {
                LatLng point = list.get(z);
                options.add(point);
            }
            line = myMap.addPolyline(options);

            /*for (int z = 0; z < list.size() - 1; z++) {
                LatLng src = list.get(z);
                LatLng dest = list.get(z + 1);
                line = myMap.addPolyline(new PolylineOptions()
                        .add(new LatLng(src.latitude, src.longitude),
                                new LatLng(dest.latitude, dest.longitude))
                        .width(5).color(Color.BLUE).geodesic(true));
            }*/

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private List < LatLng > decodePoly(String encoded) {

        List < LatLng > poly = new ArrayList < LatLng > ();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;

        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;

            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            LatLng p = new LatLng((((double) lat / 1E5)),
                (((double) lng / 1E5)));
            poly.add(p);
        }

        return poly;
    }

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
    }
}

Hope it helps. Cheers!

希望能帮助到你。干杯!

UPDATE

更新

check out this .. Creating OnDragListener for Google Map v2 Fragment

看看这个..为 Google Map v2 Fragment 创建 OnDragListener

Also check this one .. How to draw a shape on the map fragment by touching it using google map V2

还要检查这个.. 如何通过使用谷歌地图V2触摸它在地图片段上绘制形状

Some more reference .. How to get screen coordinates from marker in google maps v2 android

更多参考..如何从谷歌地图 v2 android 中的标记获取屏幕坐标

回答by TheLittleNaruto

So we do have some solution for free hand draw on map v2. Implement GoogleMap.OnMarkerDragListenerin your map activity . It'll override onMarkerDrag function.

所以我们确实有一些在地图 v2 上自由手绘的解决方案。GoogleMap.OnMarkerDragListener在您的地图活动中实施。它将覆盖 onMarkerDrag 函数。

@Override
public void onMarkerDrag(Marker marker) {

   //add the marker's latlng in a arraylist of LatLng and pass it to the loop
    for (int i = 0; i < arraylistoflatlng.size(); i++) {
         myMap.addPolyline(new PolylineOptions()
        .addAll(arraylistoflatlng)
        .width(5)
        .color(Color.RED));
    }
    }

you can pass some kind of hack for free hand like as soon as the user will touch the map, you'll have to detect that coordinates and pass it to the the onMarkerDrag . As you'll have to use the area's information for further process. For touch event you can implement GoogleMap.OnMapClickListenerand get the coordinates from it's parameter. Hope this will help :)

您可以自由地传递某种hack,就像用户触摸地图一样,您必须检测该坐标并将其传递给 onMarkerDrag 。因为您必须使用该区域的信息进行进一步处理。对于触摸事件,您可以实现GoogleMap.OnMapClickListener并从它的参数中获取坐标。希望这会有所帮助:)

回答by Nguyen Thanh An

this is google maps API V2 tutorial :

这是谷歌地图 API V2 教程:

public class MapPane extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map_activity);
        GoogleMap map = ((MapFragment) getFragmentManager()
                .findFragmentById(R.id.map)).getMap();

        map.moveCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(-18.142, 178.431), 2));

        // Polylines are useful for marking paths and routes on the map.
        map.addPolyline(new PolylineOptions().geodesic(true)
                .add(new LatLng(-33.866, 151.195))  // Sydney
                .add(new LatLng(-18.142, 178.431))  // Fiji
                .add(new LatLng(21.291, -157.821))  // Hawaii
                .add(new LatLng(37.423, -122.091))  // Mountain View
        );
    }
}

link : https://developers.google.com/maps/documentation/android/

链接:https: //developers.google.com/maps/documentation/android/