2017-05-31 207 views
2

我使用Android MapBox SDK 5.1.0-SNAPSHOT。如何以米爲單位繪製座標和半徑的圓?繪圖圈Android MapBox SDK

有一個想法來繪製多邊形多邊形。但這是非常有問題的。

回答

1

有一個想法,以吸引很多邊的多邊形

這是一種選擇,另一種選擇是將CircleLayer添加到您的活動。這是我們的運行時樣式API的一部分,您可以找到an example here

+4

謝謝你的例子。這個例子使用博物館來源。但我不知道如何用點列表創建我自己的源代碼。 –

+1

是嗎?我如何創建自定義圈子?它看起來像一個非常基本的地圖功能。 – Bilthon

1

正如Zugaldia回答的那樣,繪製一個圓形圖層是最簡單的方法。但只有當你想繪製一個圓圈時,不考慮尺寸精度。

另一種選擇是圍繞你的點繪製一個圓形的邊界,以獲得正確的距離和可視化(如果傾斜),稍後我會解釋它。

Kotlin,抱歉沒有抱歉。

第一部分,畫一個圓圈層:

mapView.getMapAsync { 
    map = it 

    // Add the source (at start, an 'empty' GeoJsonSource) 
    map?.addSource(GeoJsonSource(SOURCE_ID)) 

    // Create a circle layer from previously defined source 
    // don't forget source identifier 
    val layer = CircleLayer(CIRCLE_LAYER_ID, SOURCE_ID) 
    layer.withProperties(
      circleRadius(50f), 
      circleOpacity(.4f), 
      circleColor(Color.WHITE) 
    ) 

    map?.addLayer(layer) 
} 

而當你擁有了位置,你想周圍畫:

private fun updateCircleLayer() { 
    // Update the GeoJsonSource 
    // !!! Beware, (longitude, latitude), not the other way around !!! 
    val center = Point.fromCoordinates(doubleArrayOf(longitude, latitude)) 
    map?.getSourceAs<GeoJsonSource>(SOURCE_ID)?.setGeoJson(center) 
} 

第二部分,畫一個周長:

我改編了這個算法以適應語言和需求:https://stackoverflow.com/a/39006388/4258214

private fun getPerimeterFeature(radiusInKilometers: Double = .05, sides: Int = 64): Feature { 
    // here, currentPosition is a class property, get your lat & long as you'd like 
    val latitude = currentPosition.latitude 
    val longitude = currentPosition.longitude 

    val positions = mutableListOf<Position>() 

    // these are conversion constants 
    val distanceX: Double = radiusInKilometers/(111.319 * Math.cos(latitude * Math.PI/180)) 
    val distanceY: Double = radiusInKilometers/110.574 

    val slice = (2 * Math.PI)/sides 

    var theta: Double 
    var x: Double 
    var y: Double 
    var position: Position 
    for (i in 0..sides) { 
     theta = i * slice 
     x = distanceX * Math.cos(theta) 
     y = distanceY * Math.sin(theta) 

     position = Position.fromCoordinates(longitude + x, latitude + y) 
     positions.add(position) 
    } 

    return Feature.fromGeometry(Polygon.fromCoordinates(listOf(positions))) 
} 

請參閱updateCircleLayer()在第一部分提供返回FeatureGeoJSonSource就是這樣。

希望這會有所幫助。玩的開心 !

1

基於@Xalamadrax答案,我簡化了他的一段代碼並用java編譯了它。

private PolygonOptions generatePerimeter(LatLng centerCoordinates, double radiusInKilometers, int numberOfSides) { 
    List<LatLng> positions = new ArrayList<>(); 
    double distanceX = radiusInKilometers/(111.319 * Math.cos(centerCoordinates.getLatitude() * Math.PI/180)); 
    double distanceY = radiusInKilometers/110.574; 

    double slice = (2 * Math.PI)/numberOfSides; 

    double theta; 
    double x; 
    double y; 
    LatLng position; 
    for (int i = 0; i < numberOfSides; ++i) { 
     theta = i * slice; 
     x = distanceX * Math.cos(theta); 
     y = distanceY * Math.sin(theta); 

     position = new LatLng(centerCoordinates.getLatitude() + y, 
       centerCoordinates.getLongitude() + x); 
     positions.add(position); 
    } 
    return new PolygonOptions() 
      .addAll(positions) 
      .fillColor(Color.BLUE) 
      .alpha(0.4f); 
} 

並將其添加到地圖:

mMapView.getMapAsync(new OnMapReadyCallback() { 
    @Override 
    public void onMapReady(MapboxMap mapboxMap) { 
     mapboxMap.addPolygon(generatePerimeter(
       new LatLng(48.8566d, 2.3522d), 
       100, 
       64)); 
    } 
}); 

編輯:我是很新的,所以也許這可以提高mapbox。