在 Google 地图中使用 dragListener 可编辑多个多边形

Posted

技术标签:

【中文标题】在 Google 地图中使用 dragListener 可编辑多个多边形【英文标题】:Editable multiple polygon using dragListener in Google Maps 【发布时间】:2020-10-09 16:34:05 【问题描述】:

我想使用拖动侦听器实现多个可编辑的多边形。我可以绘制多个多边形,但我不知道如何使其可编辑。

我可以移动当前多边形的标记,但是当我尝试移动前一个多边形的标记时,应用程序崩溃了。我尝试保存多边形列表,但无法拖动标记。

请在此处查看我的代码。

@Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        if (readyToGo()) 
            setContentView(R.layout.activity_maps);
            // Obtain the SupportMapFragment and get notified when the map is ready to be used.
            SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map);
            mapFragment.getMapAsync(this);

            if (savedInstanceState == null) 
                mapFragment.getMapAsync(this);
            

            mapFragment.getMapAsync(this);
        
    

    @Override
    public void onMapReady(GoogleMap googleMap) 
        mMap = googleMap;
        CameraUpdate center =
                CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
                        -73.98180484771729));
        CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
        mMap.moveCamera(center);
        mMap.animateCamera(zoom);
        mMap.setIndoorEnabled(false);

        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() 
            @Override
            public void onMapClick(LatLng latLng) 

                Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
                marker.setTag(latLng);
                markerList.add(marker);
                points.add(latLng);
                drawPolygon(points);
            
        );


        mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() 
            @Override
            public void onMarkerDragStart(Marker marker) 

            

            @Override
            public void onMarkerDrag(Marker marker) 
                updateMarkerLocation(marker, false);
            

            @Override
            public void onMarkerDragEnd(Marker marker) 
                updateMarkerLocation(marker, true);

            
        );

    

    public void closePolygon(View view) 

    

    public void newPolygon(View view) 

//
        points.clear();
        markerList.clear();
        polygon = null;
//        mMap.clear();
    

    private void updateMarkerLocation(Marker marker, boolean calculate) 
        LatLng latLng = (LatLng) marker.getTag();
        int position = points.indexOf(latLng);
        points.set(position, marker.getPosition());
        marker.setTag(marker.getPosition());
        drawPolygon(points);

    

    private void drawPolygon(List<LatLng> latLngList) 
        if (polygon != null) 
            polygon.remove();
        
        polygonOptions = new PolygonOptions();
        polygonOptions.addAll(latLngList);
        polygon = mMap.addPolygon(polygonOptions);

    


【问题讨论】:

“多个多边形”是什么意思 - 发布的代码通过删除/重新添加附加点来维护一个多边形。 当您按下新多边形时,它正在绘制新多边形。 @Andy 请查看此链接以获取完整代码github.com/arpit999/Polygon 好的 - 这必须是一个按钮或其他东西 - 我让你的代码按照发布的方式运行并且效果很好,但我没有新的多边形功能。 是的,有新多边形的按钮,请查看来自 github @Andy 的完整代码 我能获得绘制多边形且标记可移动的android示例代码 【参考方案1】:

基本上,这种方法将标记和点保存为与每个多边形相关联的集合。它通过假设在 5 个标记后创建一个新多边形(相当于添加多边形)来简化事情。

更新:使用 github 布局中定义的“新多边形”按钮。按钮侦听器只是设置一个标志,而不是使用 size=5 检查,而是用标志替换检查。

维护从任何标记到其对应列表的映射以供updateMarkerLocation 方法使用。

所有这一切都基于这样一个事实,即任何标记都具有由地图 API getId() 提供的唯一 ID,该 ID 在实践中是一个类似于“m7”的字符串。

我已经列出了更新的部分:

// Map a marker id to its corresponding list (represented by the root marker id)
HashMap<String,String> markerToList = new HashMap<>();

// A list of markers for each polygon (designated by the marker root).
HashMap<String,List<Marker>> polygonMarkers = new HashMap<>();

// A list of polygon points for each polygon (designed by the marker root).
HashMap<String,List<LatLng>> polygonPoints = new HashMap<>();

// List of polygons (designated by marker root).
HashMap<String,Polygon> polygons = new HashMap<>();

// The active polygon (designated by marker root) - polygon added to.
String markerListKey;

// Flag used to record when the 'New Polygon' button is pressed.  Next map
// click starts a new polygon.
boolean newPolygon = false;

@Override
public void onMapReady(GoogleMap googleMap) 
    mMap = googleMap;
    CameraUpdate center =
            CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
                    -73.98180484771729));
    CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
    mMap.moveCamera(center);
    mMap.animateCamera(zoom);
    mMap.setIndoorEnabled(false);

    Button b = findViewById(R.id.bt_new_polygon);
    b.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            newPolygon = true;
        
    );

    mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() 
        @Override
        public void onMapClick(LatLng latLng) 

            Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
            marker.setTag(latLng);

            // Special case for very first marker.
            if (polygonMarkers.size() == 0) 
                polygonMarkers.put(marker.getId(),new ArrayList<Marker>());
                // only 0 or 1 polygons so just add it to new one or existing one.
                markerList = new ArrayList<>();
                points = new ArrayList<>();
                polygonMarkers.put(marker.getId(),markerList);
                polygonPoints.put(marker.getId(),points);
                markerListKey = marker.getId();
            

            if (newPolygon) 
                newPolygon = false;
                markerList = new ArrayList<>();
                points = new ArrayList<>();
                polygonMarkers.put(marker.getId(),markerList);
                polygonPoints.put(marker.getId(),points);
                markerListKey = marker.getId();
            

            markerList.add(marker);
            points.add(latLng);
            markerToList.put(marker.getId(),markerListKey);

            drawPolygon(markerListKey, points);
        
    );


private void updateMarkerLocation(Marker marker, boolean calculate) 

    // Use the marker to figure out which polygon list to use...
    List<LatLng> pts = polygonPoints.get(markerToList.get(marker.getId()));
    
    // This is much the same except use the retrieved point list.
    LatLng latLng = (LatLng) marker.getTag();
    int position = pts.indexOf(latLng);
    pts.set(position, marker.getPosition());
    marker.setTag(marker.getPosition());
    drawPolygon(markerToList.get(marker.getId()),pts);



private void drawPolygon(String mKey, List<LatLng> latLngList) 

    // Use the existing polygon (if any) for the root marker.
    Polygon polygon = polygons.get(mKey);
    if (polygon != null) 
        polygon.remove();
    
    polygonOptions = new PolygonOptions();
    polygonOptions.addAll(latLngList);
    polygon = mMap.addPolygon(polygonOptions);
    
    // And update the list for the root marker.
    polygons.put(mKey,polygon);

初始

通过点击地图添加的 3 个多边形的初始集合...

修改

然后在每个多边形中显示一个点的图像被拉伸...

【讨论】:

感谢您的回答我会尝试并让您知道 这是我正在寻找的,但有一个问题,它仅限于 5 个标记,我希望在单击按钮后获得新的多边形。 查看了 github 项目中的布局并向 bt_new_polygon 添加了一个按钮侦听器,它只是设置了一个标志。在下一张地图上单击一个新的多边形开始 - 而不是使用多边形大小。不完全确定预期的用户体验,但希望能给你一些可以使用的东西。也不确定关闭按钮应该如何工作。

以上是关于在 Google 地图中使用 dragListener 可编辑多个多边形的主要内容,如果未能解决你的问题,请参考以下文章

使用 AGM 拖动地图时如何将 Google 地图标记保持在中心?

在 jQuery Mobile 中使用 longclick/taphold 和 Google 地图?

在 Java 桌面应用程序中使用的 Google 地图替代方案

我可以在 osmdroid 中使用 Google 地图图块吗?

如何在网上(google)下载卫星地图

在 Android 的 Fragment 中使用 Google 地图