简体   繁体   English

如何在谷歌中使用 latlng 的字符串数组绘制多边形 map

[英]how to draw polygon using string array of latlng in google map

In my app, i have recyclerview which contain imagview and this imageview contain static map image by using coordinates which i store in sqlite. and when i click on that image i am passing that coordinates in string array format to other map activity and then using this string array coordinates again draw the same polygon which static map hold into google map. but i don't understand how to do this.在我的应用程序中,我有包含 imagview 的 recyclerview,这个 imageview 包含 static map 图像,使用我存储在 sqlite 中的坐标。当我单击该图像时,我将该坐标以字符串数组格式传递给其他 map 活动,然后使用此字符串数组坐标再次绘制相同的多边形,其中 static map 保存到谷歌 map。但我不知道如何执行此操作。

I tried following code but not working:我尝试了以下代码但没有工作:

this is code of my adapter class where i display static map on image view and then using intent pass the coordinates to map activity这是我的适配器 class 的代码,我在图像视图上显示 static map,然后使用 intent 将坐标传递给 map 活动

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

this is my map activity where i want to draw polygon using coordinates:这是我的 map 活动,我想在其中使用坐标绘制多边形:

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

then in map ready method()然后在 map ready method()

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

}

In my app, i have recyclerview which contain imagview and this imageview contain static map image by using coordinates which i store in sqlite. In my app, i have recyclerview which contain imagview and this imageview contain static map image by using coordinates which i store in sqlite. and when i click on that image i am passing that coordinates in string array format to other map activity and then using this string array coordinates again draw the same polygon which static map hold into google map. and when i click on that image i am passing that coordinates in string array format to other map activity and then using this string array coordinates again draw the same polygon which static map hold into google map. but i don't understand how to do this.但我不明白该怎么做。

I tried following code but not working:我尝试了以下代码但无法正常工作:

this is code of my adapter class where i display static map on image view and then using intent pass the coordinates to map activity这是我的适配器 class 的代码,我在其中显示 static map 在图像视图上,然后使用意图将坐标传递给 Z1D7AEZ8B8ED512FE49014

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

this is my map activity where i want to draw polygon using coordinates:这是我想使用坐标绘制多边形的 map 活动:

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

then in map ready method()然后在 map 准备方法()

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

}

If you want to load your map in google map's application then you can go with the below approch:如果你想在谷歌地图的应用程序中加载你的 map,那么你可以使用以下方法加载 go:

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

Or If you want to load it inside your app try with MapActivity where you need to first enable google map API and then your applied coordinates will be displayed on the map或者如果你想在你的应用程序中加载它,请尝试使用 MapActivity,你需要首先启用谷歌 map API 然后你应用的坐标将显示在 map

Please check below link this will be useful to integrate this请检查下面的链接,这将有助于集成它

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

Call this from your button click listener:从您的按钮点击侦听器中调用它:

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

Source: Maps URLs资料来源: 地图网址

If I understand your question correctly, you need to: first show a static map, then, after clicking, show the same static map, but with several polygons on it.如果我正确理解你的问题,你需要:首先显示一个 static map,然后,点击后,显示相同的 static map,但上面有几个多边形。 As in the case of the quiz, when the first (question) Activity of the user is asked for the right place of an object, and the second (answer) Activity displays the correct place of the object.与测验的情况一样,当用户的第一个(问题) Activity被要求输入 object 的正确位置时,第二个(答案) Activity显示 object 的正确位置。

For this you need:为此你需要:

1) bind the image of static map to geodetic coordinates; 1)将static map的图片绑定到大地坐标;

2) implement GoogleMap.addPolygon() method for draw polygone on it. 2) 实现GoogleMap.addPolygon()方法在其上绘制多边形。

Both of that task is not trivial in general, so easiest ways is:这两项任务一般来说都不是微不足道的,所以最简单的方法是:

1) If you want quick right answer shown in second activity, request and get from Static Map API in yours first Activity two maps: first - just with map image, and second - same map, but already with polygons. 1) 如果您想要在第二个活动中显示快速正确答案,请在您的第一个Activity中请求并从 Static Map API 获取两张地图:第一张 - 仅带有 map 图像,第二张 - 相同的 map,但已经带有多边形。 First image you show in that activity, and to second Activity (which you show after click) you show second image already with polygons.您在该活动中显示的第一张图片,以及第二个Activity (您在单击后显示)显示的第二张图片已经带有多边形。 Or request second image in second Activity if you want to show answer only for clicked maps.或者,如果您只想为点击的地图显示答案,则在第二个Activity中请求第二张图片。 In Official Documentation you can find how to get static map image with polygone on it (take a look at the path parameter):官方文档中,您可以找到如何获取带有多边形的 static map 图像(查看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

Now maps Static API URLs are restricted to 8192 characters in size .现在映射 Static API URL 的大小限制为 8192 个字符 So if your polygon has a lot of points you should use encoded polyline format for polygon points.因此,如果您的多边形有很多点,您应该为多边形点使用编码折线格式 You can encode your polygon with PolyUtil.encode() method of Maps SDK for Android Utility Library .您可以使用Maps SDK for Android Utility LibraryPolyUtil.encode()方法对多边形进行编码。

2) (IMHO better) use MapView/MapFragment Lite Mode of Maps SDK for Android that can serve a bitmap image of a map, offering limited interactivity to the user. 2)(恕我直言更好)为 Android 使用地图 SDK 的MapView/MapFragment Lite 模式,可以提供 map 的 bitmap 图像,为用户提供有限的交互性。 Polylines are supported in this mode and you can save some traffic.此模式支持折线,您可以节省一些流量。 In that case you should place MapView' or 'MapFragment in first activity and MapView/MapFragment with same settings (size, camera position etc.) in second activity and when user click on map of first activity just draw polygon of the map of the second and show it.在这种情况下,您应该在第一个活动中放置MapView' or 'MapFragment ,在第二个活动中放置具有相同设置(大小、相机 position 等)的MapView/MapFragment ,当用户单击第一个活动的 map 时,只需绘制第二个活动的 map 的多边形并展示它。 The lite mode functionality for shapes matches the full API :形状的精简模式功能与完整的 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));

To draw polygons rectangle correctly try this sort function:要正确绘制多边形矩形,请尝试这种排序 function:

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
    }

This works for me, based in this swift answer这对我有用,基于这个swift 答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Google Map(Android,Java)中找到多边形的中心Latlng - How to find Center Latlng of a polygon in Google Map (Android, Java) 如何按 LatLng 的 ArrayList 中的值顺序对 LatLng、String 的映射进行排序 - How to sort a Map of LatLng,String by the order of values in an ArrayList of LatLng 如何使用Polygon类在libGdx中绘制六边形图? - How to draw a hexagon map in libGdx using the Polygon class? 如何将latlng数组列表的值传递给多边形 - How can i pass values of latlng array list to polygon 如何在 android 应用程序中使用 map 框创建自定义 Air map 视图并绘制多边形 - How to create a custom Air map view and draw a polygon using map box in android application 如何使用带有json的Map从数据库设置map latlng值? - how using Map with json to set map latlng value from database? 如何使用javafx以多维数组为参数绘制多边形 - How to draw a polygon with javafx, with a multidimensional array as parameter 如何检查 LatLng 点是否位于 google maps android 上 geojson 层上的多边形内 - How to check if a LatLng point lies inside a polygon on the geojson layer on google maps android 如何使用javacv编辑此方法来绘制多边形? - How to edit this method to draw polygon using javacv? 如何使用Java绘制不完整的多边形 - How to draw an incomplete Polygon using Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM