簡體   English   中英

如何在谷歌中使用 latlng 的字符串數組繪制多邊形 map

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

在我的應用程序中,我有包含 imagview 的 recyclerview,這個 imageview 包含 static map 圖像,使用我存儲在 sqlite 中的坐標。當我單擊該圖像時,我將該坐標以字符串數組格式傳遞給其他 map 活動,然后使用此字符串數組坐標再次繪制相同的多邊形,其中 static map 保存到谷歌 map。但我不知道如何執行此操作。

我嘗試了以下代碼但沒有工作:

這是我的適配器 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);
        }
    });

這是我的 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);
    }

然后在 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. 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. 但我不明白該怎么做。

我嘗試了以下代碼但無法正常工作:

這是我的適配器 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);
        }
    });

這是我想使用坐標繪制多邊形的 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);
    }

然后在 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);

}

如果你想在谷歌地圖的應用程序中加載你的 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);

或者如果你想在你的應用程序中加載它,請嘗試使用 MapActivity,你需要首先啟用谷歌 map API 然后你應用的坐標將顯示在 map

請檢查下面的鏈接,這將有助於集成它

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

從您的按鈕點擊偵聽器中調用它:

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

資料來源: 地圖網址

如果我正確理解你的問題,你需要:首先顯示一個 static map,然后,點擊后,顯示相同的 static map,但上面有幾個多邊形。 與測驗的情況一樣,當用戶的第一個(問題) Activity被要求輸入 object 的正確位置時,第二個(答案) Activity顯示 object 的正確位置。

為此你需要:

1)將static map的圖片綁定到大地坐標;

2) 實現GoogleMap.addPolygon()方法在其上繪制多邊形。

這兩項任務一般來說都不是微不足道的,所以最簡單的方法是:

1) 如果您想要在第二個活動中顯示快速正確答案,請在您的第一個Activity中請求並從 Static Map API 獲取兩張地圖:第一張 - 僅帶有 map 圖像,第二張 - 相同的 map,但已經帶有多邊形。 您在該活動中顯示的第一張圖片,以及第二個Activity (您在單擊后顯示)顯示的第二張圖片已經帶有多邊形。 或者,如果您只想為點擊的地圖顯示答案,則在第二個Activity中請求第二張圖片。 官方文檔中,您可以找到如何獲取帶有多邊形的 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

現在映射 Static API URL 的大小限制為 8192 個字符 因此,如果您的多邊形有很多點,您應該為多邊形點使用編碼折線格式 您可以使用Maps SDK for Android Utility LibraryPolyUtil.encode()方法對多邊形進行編碼。

2)(恕我直言更好)為 Android 使用地圖 SDK 的MapView/MapFragment Lite 模式,可以提供 map 的 bitmap 圖像,為用戶提供有限的交互性。 此模式支持折線,您可以節省一些流量。 在這種情況下,您應該在第一個活動中放置MapView' or 'MapFragment ,在第二個活動中放置具有相同設置(大小、相機 position 等)的MapView/MapFragment ,當用戶單擊第一個活動的 map 時,只需繪制第二個活動的 map 的多邊形並展示它。 形狀的精簡模式功能與完整的 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));

要正確繪制多邊形矩形,請嘗試這種排序 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
    }

這對我有用,基於這個swift 答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM