【问题标题】:how to draw polygon using string array of latlng in google map如何在谷歌地图中使用 latlng 字符串数组绘制多边形
【发布时间】:2020-07-27 02:45:35
【问题描述】:

在我的应用程序中,我有包含 imagview 的 recyclerview,并且此 imageview 通过使用我存储在 sqlite 中的坐标包含静态地图图像。当我单击该图像时,我将该坐标以字符串数组格式传递给其他地图活动,然后再次使用此字符串数组坐标绘制静态地图保存到谷歌地图中的相同多边形。但我不明白该怎么做。

我尝试了以下代码但无法正常工作:

这是我的适配器类的代码,我在图像视图上显示静态地图,然后使用意图将坐标传递给地图活动

   String url ="https://maps.googleapis.com/maps/api/staticmap?";
    url+="&zoom=18";
    url+="&size=300x300";
    url+="&maptype=satellite";
    url+="&path=color:green|fillcolor:0xFFFF0033|"+ Coordinates;
    url+="&key=" + "AIzaSyCj80x6E****Lx_KFsHKlogV0";
    Picasso.get().load(url).into(holder.poly_image);

    holder.poly_image.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {


            Intent i = new Intent(mCtx, EditMapsActivity.class);
            i.putExtra("img", Poly_Coords);
            mCtx.startActivity(i);
        }
    });

这是我想使用坐标绘制多边形的地图活动:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_edit_maps);

    // Obtain the SupportMapFragment and get notified when the map is ready 
   to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) 
    getSupportFragmentManager().findFragmentById(R.id.mapView);
    mapFragment.getMapAsync(EditMapsActivity.this);
    Intent intent = getIntent();
    String staticPolyCoords = intent.getStringExtra("img");
    Log.d("Log", "Polygon Coords" + staticPolyCoords);

    String answer = staticPolyCoords;
    ArrayList<Location> arrayListLatLng = new ArrayList<>();
    answer = answer.replace("lat/lng: (" , "");
    answer = answer.replace(")" , "");
    answer = answer.replace("]","");
    answer = answer.replace("[","");
    String[] arrayLatLng = answer.split(",");
    Log.d("LOG_TAG", "Polygon Coordinates" +  arrayLatLng);

    for(int i = 0 ; i < arrayLatLng.length ; i++ ){

       LatLng Cooordinate_Point = new 
       LatLng((Double.parseDouble(arrayLatLng[i])), 
       Double.parseDouble(arrayLatLng[i+1]));
        Log.d("LOG_TAG", "Polygon Coordinates" +  Cooordinate_Point);
        latLngList.add(Cooordinate_Point);
    }

然后在map ready方法()中

 @Override
public void onMapReady(GoogleMap googleMap) {
    myMap = googleMap;

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        DrawPolygon(latLngList);

    }


  private void DrawPolygon(List<LatLng> latLngList) {

  /*  myMap.addPolygon(new PolygonOptions().strokeColor(Color.GREEN).fillColor(0x7F228B22).add(latLngList));*/

    Polygon polygon = myMap.addPolygon(new PolygonOptions()
            .clickable(true)
            .add(latLngList));
    // Store a data object with the polygon, used here to indicate an arbitrary type.
    polygon.setTag("alpha");
    polygon.setStrokeWidth(3);
    polygon.setStrokeColor(Color.GREEN);
    polygon.setFillColor(0x7F228B22);

}

【问题讨论】:

  • 您想在您自己的活动中加载包含MapView的网址?
  • 你应该在 webview 而不是 imageview 中加载 url
  • @GiorgioAntonioli 是的
  • 我认为这很简单。访问此网站Polygon Tutorial

标签: java android polygon google-static-maps


【解决方案1】:

从你的按钮点击监听器调用这个:

Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("https://www.google.com/maps/@?api=1&map_action=map&center=" + Coordinates));
mCtx.startActivity(i);

来源:Maps URLs

【讨论】:

  • 我不想在网络上打开我的静态地图。当我单击静态地图图像视图时,我只想使用我的坐标在地图视图上绘制多边形。我更新我的帖子请看看我在做什么
【解决方案2】:

如果您想在谷歌地图的应用程序中加载您的地图,那么您可以使用以下方法:

String geoUri = "http://maps.google.com/maps?q=loc:" + latitude + "," + longitude + " (" + mTitle + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(geoUri));
context.startActivity(intent);

或者,如果您想在您的应用中加载它,请尝试使用 MapActivity,您需要先启用谷歌地图 API,然后您应用的坐标将显示在地图上

请检查下面的链接,这将有助于整合它

https://developers.google.com/maps/documentation/android-sdk/start

【讨论】:

    【解决方案3】:

    如果我正确理解您的问题,您需要:首先显示一个静态地图,然后单击后显示相同的静态地图,但上面有几个多边形。与测验的情况一样,当用户的第一个(问题)Activity 被询问对象的正确位置时,第二个(答案)Activity 显示对象的正确位置。

    为此,您需要:

    1) 将静态地图图像绑定到大地坐标;

    2) 实现GoogleMap.addPolygon() 方法在其上绘制多边形。

    一般来说,这两项任务都不是微不足道的,所以最简单的方法是:

    1) 如果您想在第二个活动中显示快速正确的答案,请首先在您的 Activity 中请求并从静态地图 API 获取两张地图:第一张 - 仅带有地图图像,第二张 - 相同的地图,但已经带有多边形。您在该活动中显示的第一张图像,以及第二张Activity(单击后显示)您已经显示了第二张带有多边形的图像。如果您只想为点击的地图显示答案,或者在第二张Activity 中请求第二张图片。在Official Documentation 中,您可以找到如何获取带有多边形的静态地图图像(查看path 参数):

    https://maps.googleapis.com/maps/api/staticmap ?size=400x400&center=40.653279,-73.959816&zoom=11 &path=fillcolor:0xAA000033%7Ccolor:0xFFFFFF00%7Cenc:}zswFtikbMjJzZ%7CRdPfZ}DxWvBjWpF~IvJnEvBrMvIvUpGtQpFhOQdKpz@bIx{A%7CPfYlvApz@bl@tcAdTpGpVwQtX}i@%7CGen@lCeAda@bjA%60q@v}@rfAbjA%7CEwBpbAd_@he@hDbu@uIzWcWtZoTdImTdIwu@tDaOXw_@fc@st@~VgQ%7C[uPzNtA%60LlEvHiYyLs^nPhCpG}SzCNwHpz@cEvXg@bWdG%60]lL~MdTmEnCwJ[iJhOae@nCm[%60Aq]qE_pAaNiyBuDurAuB}}Ay%60@%7CEKv_@?%7C[qGji@lAhYyH%60@Xiw@tBerAs@q]jHohAYkSmW?aNoaAbR}LnPqNtMtIbRyRuDef@eT_z@mW_Nm%7CB~j@zC~hAyUyJ_U{Z??cPvg@}s@sHsc@_z@cj@kp@YePoNyYyb@_iAyb@gBw^bOokArcA}GwJuzBre@i\tf@sZnd@oElb@hStW{]vv@??kz@~vAcj@zKa%60Atf@uQj_Aee@pU_UrcA &key=YOUR_API_KEY

    现在映射静态 API URL 为 restricted to 8192 characters in size。因此,如果您的多边形有很多点,您应该使用encoded polyline format 来表示多边形点。您可以使用Maps SDK for Android Utility LibraryPolyUtil.encode() 方法对多边形进行编码。

    2) (恕我直言,更好)使用 Maps SDK for Android 的 MapView/MapFragment Lite Mode 可以提供地图的位图图像,为用户提供有限的交互性。此模式支持折线,您可以节省一些流量。在这种情况下,您应该将MapView' or 'MapFragment 放置在第一个活动中,将MapView/MapFragment 放置在第二个活动中,并使用相同的设置(大小、相机位置等),当用户单击第一个活动的地图时,只需绘制第二个活动的地图的多边形并显示它。形状的精简模式功能与full API

    GoogleMap map;
    // ... get a map.
    // Add a triangle in the Gulf of Guinea
    Polygon polygon = map.addPolygon(new PolygonOptions()
         .add(new LatLng(0, 0), new LatLng(0, 5), new LatLng(3, 5), new LatLng(0, 0))
         .strokeColor(Color.RED)
     .fillColor(Color.BLUE));
    

    【讨论】:

    • 请查看我编辑的帖子。我到底想实现什么
    • @Felicity 使用 Lite 模式方法 - 它正是为此目的而创建的。
    • @Felicity 如果你使用Lite Node方式,你应该将String的经纬度值转换为LatLng类型,然后将它们全部添加到PolygonOptions()
    【解决方案4】:

    使用此代码进行转换:

        String answer = staticPolyCoords;
        answer = answer.replace("lat/lng:" , "");
        answer = answer.replace(")" , "]");
        answer = answer.replace("(" , "[");
    
        try {
            JSONArray jsonArray = new JSONArray(answer);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONArray latLong = jsonArray.getJSONArray(i);
                double lat = latLong.getDouble(0);
                double lon = latLong.getDouble(1);
                coordinates.add(new LatLng(lat, lon));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    

    然后在你的 drawPolygon 方法中为每个循环尝试这个:

     PolygonOptions poly = new PolygonOptions();
        for (LatLng latLng : coordinates) {
            //use the coordinates.
            poly.addAll(Collections.singleton(latLng));
        }
    
    
        Polygon polygon = myMap.addPolygon(poly);
       //add here your set methods
    
        myMap.moveCamera(CameraUpdateFactory.newLatLng(coordinates.get(3)));
        CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
        myMap.animateCamera(zoom);
     }
    

    【讨论】:

    • 如何将此多边形添加到多边形
    • 你的 mapobject.addPolygon(poly)
    • 对不起,我不明白
    • 多边形多边形 = myMap.adPolygon(poly);
    【解决方案5】:

    要正确绘制多边形矩形试试这个排序功能:

    fun sortConvexs(coordinates: MutableList<LatLng>): MutableList<LatLng> {
    
            val input = coordinates
    
            // Returns a positive value, if OAB makes a counter clockwise turn,negative for clockwise turn, and zero if the points are collinear.
    
            fun cross(P: LatLng, _A: LatLng, _B: LatLng): Double {
                val part1 = (_A.longitude - P.longitude) * (_B.latitude - P.latitude)
                val part2 = (_A.latitude - P.latitude) * (_B.longitude - P.longitude)
                return part1 - part2
            }
    
            // Sort points
    
            var points = input.sortedWith(
                Comparator<LatLng> { coordinate0, coordinate1 ->
                    when {
                        (coordinate0.longitude == coordinate1.longitude) && (coordinate0.latitude < coordinate1.latitude) -> 1
                        (coordinate0.longitude < coordinate1.longitude) -> -1
                        else -> 0
                    }
                }
            )
    
            // Build the lower hull
    
            var lower: MutableList<LatLng> = ArrayList<LatLng>()
    
            points.forEach { p ->
    
                while (lower.size >= 2 && cross(lower[lower.size - 2], lower[lower.size - 1], p) <= 0) {
                    lower.removeAt(lower.size - 1)
                }
    
                lower.add(p)
    
            }
    
            // Build upper hull
    
            var upper: MutableList<LatLng> = ArrayList<LatLng>()
    
            points = points.asReversed()
    
            points.forEach { p ->
                while (upper.size >= 2 && cross(upper[upper.size - 2], upper[upper.size - 1], p) <= 0) {
                    upper.removeAt(upper.size - 1)
                }
    
                upper.add(p)
            }
    
            // Last point of upper list is omitted because it is repeated at the beginning of the lower list.
    
            upper.removeAt(upper.size - 1)
    
    
            // Concatenation of the lower and upper hulls gives the total points.
    
            return (upper + lower).toMutableList()
        }
    
    
        fun getApproximateCenter(points: MutableList<LatLng>): LatLng {
            // Calc bounds first
            val boundsBuilder = LatLngBounds.builder()
            points.forEach {
                boundsBuilder.include(it)
            }
            val polygonBounds = boundsBuilder.build()
    
            val centerPoint = polygonBounds.center
    
            // Center point is inside the polygon, return it
            if (PolyUtil.containsLocation(centerPoint, points, true)) {
                return centerPoint
            }
    
            // Center point is out of bounds
            // Sample points at fixed percentages of the bounding box’s width East and West of the center point.
            val maxSearchSteps = 10
            var testPos: LatLng = centerPoint
    
            // Calculate NorthWest point so we can work out height of polygon NW->SE
            val northWest = LatLng(polygonBounds.northeast.latitude, polygonBounds.southwest.longitude)
    
            // Work out how tall and wide the bounds are and what our search
            // increment will be
            val boundsHeight = SphericalUtil.computeDistanceBetween(northWest, polygonBounds.southwest)
            val heightIncr = boundsHeight / maxSearchSteps
    
            val boundsWidth = SphericalUtil.computeDistanceBetween(northWest, polygonBounds.northeast)
            val widthIncr = boundsWidth / maxSearchSteps
    
            // Expand out from Centroid and find a point within polygon at
            // 0, 90, 180, 270 degrees
            for (n in 1..maxSearchSteps) {
                // Test point North of Centroid
                testPos = SphericalUtil.computeOffset(
                    centerPoint,
                    (heightIncr * n),
                    0.0
                )
                if (PolyUtil.containsLocation(testPos, points, true)) {
                    break
                }
    
                // Test point East of Centroid
                testPos = SphericalUtil.computeOffset(
                    centerPoint,
                    (widthIncr * n),
                    90.0
                )
                if (PolyUtil.containsLocation(testPos, points, true)) {
                    break
                }
    
                // Test point South of Centroid
                testPos = SphericalUtil.computeOffset(
                    centerPoint,
                    (heightIncr * n),
                    180.0
                )
                if (PolyUtil.containsLocation(testPos, points, true)) {
                    break
                }
    
                // Test point West of Centroid
                testPos = SphericalUtil.computeOffset(
                    centerPoint,
                    (widthIncr * n),
                    270.0
                )
                if (PolyUtil.containsLocation(testPos, points, true)) {
                    break
                }
            }
    
            return testPos
        }
    

    这对我有用,基于 swift answer

    【讨论】:

      猜你喜欢
      • 2014-04-02
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-06
      相关资源
      最近更新 更多