您好,我想使用這個 api nominatim.org來查找一個地址的 svg 形狀和 latLng 坐標。我在顫振中呼叫了這個 api,并嘗試在開放街道地圖的顫振代碼中通過 Polygon 顯示它這是我的代碼
late PolyEditor polyEditor;
List<Polygon> polygons = [];
var testPolygon = Polygon(
color: Colors.black.withOpacity(0.3),
points: [],
borderColor: Colors.black,
isFilled: true,
borderStrokeWidth: 1.0);
@override
void initState() {
super.initState();
polyEditor = PolyEditor(
addClosePathMarker: true,
points: testPolygon.points,
pointIcon: const Icon(
Icons.lens,
size: 15,
color: Colors.black,
),
intermediateIcon: const Icon(Icons.lens, size: 15, color: Colors.black),
callbackRefresh: () => {setState(() {})},
);
polygons.add(testPolygon);
}
SearchController searchController = Get.put(SearchController());
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
alignment: Alignment.center,
children: [
Center(
child: FlutterMap(
options: MapOptions(
allowPanningOnScrollingParent: false,
onTap: (_, ll) {
print(ll);
polyEditor.add(testPolygon.points, ll);
},
plugins: [
DragMarkerPlugin(),
],
center: LatLng(32.5231, 51.6765),
zoom: 9.4,
),
layers: [
TileLayerOptions(
urlTemplate:
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
subdomains: ['a', 'b', 'c']),
PolygonLayerOptions(polygons: polygons),
DragMarkerPluginOptions(markers: polyEditor.edit()),
],
),
),
我呼叫了這個 api 并試圖將這個 svg 顯示為一個多邊形
"svg": "M 13.397511 -52.517283599999999 L 13.397829400000001 -52.517299800000004
13.398131599999999 -52.517315099999998 13.398159400000001 -52.517112099999999 13.3975388
-52.517080700000001 Z",
但我不知道如何將此 svg 坐標字串轉換為 Polygon 并在呼叫此 api 并接收此 svg 時將其顯示在地圖上
我用過這個插件
import 'package:flutter_map_line_editor/polyeditor.dart';
結果應該是這樣 看這張圖片
uj5u.com熱心網友回復:
你面臨幾個問題:
- 從 nominatim 檢索到的 svg 資料不是多邊形而是路徑
- 此外,它描述了一個點,即它沒有任何高度或寬度。
- 很可能,polyeditor 需要一個基于地理資料坐標陣列的適當多邊形。
更改 nominatim 查詢以獲取多邊形坐標
您可以將查詢更改為如下內容:
https://nominatim.openstreetmap.org/search?q=London&format=json&polygon_geojson=1
大多數地址搜索查詢不會回傳多邊形,除非它們是像“London Downing street 10”這樣的景點或公共建筑。
如果您正在搜索城市、縣、州、地區或景點,json 回應將包含描述查詢區域邊界的多邊形坐標。
polygon_geojson=1引數將回傳一個可以在地圖上顯示的陣列多邊形坐標。
不幸的是,您需要更改坐標順序才能在傳單中使用它們,因為 geojson 將回傳[lon, lng]而不是[lat, lon]
Js示例從nominatim中獲取多邊形
您可以將此示例翻譯為使用顫振。
顯示代碼片段
function initMap(lat, lon, zoom, coords = [], bBox = []) {
var map = L.map("map").setView([lat, lon], zoom);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution: "? OpenStreetMap"
}).addTo(map);
var marker = L.marker([lat, lon]).addTo(map);
if (coords.length) {
/**
* change coordinate order from [lon, lat] to [lat, lon]
* and reduce number of polygon vertices to 64
*/
let polygonPoints = getGeoJsonPoly(coords, 64);
var polygon = L.polygon(polygonPoints).addTo(map);
}
var southWest = new L.LatLng(bBox[0], bBox[2]),
northEast = new L.LatLng(bBox[1], bBox[3]),
bounds = new L.LatLngBounds(southWest, northEast);
map.fitBounds(bounds);
}
let query = "City-of-London";
//query = "London Downing street 10";
let url = `https://nominatim.openstreetmap.org/search?q=${query}&format=json&polygon_geojson=1`;
fetchJson(url);
function fetchJson(url) {
fetch(url)
.then((response) => response.json())
.then(function(data) {
let result = data[0];
let type = result.osm_type;
if (type != 'relation') {
result = data[1];
}
let [lat, lon] = [result.lat, result.lon];
let coords = result["geojson"]["coordinates"][0];
let bBox = result.boundingbox ? result.boundingbox : [];
initMap(lat, lon, 10, coords, bBox);
})
.catch(function(error) {
console.error(error);
});
}
function getGeoJsonPoly(coords, vertices = 0) {
let coordsL = coords.length;
let step = vertices != 0 ? Math.ceil(coordsL / vertices) : 1;
let polygonPoints = [];
for (let i = 0; i < coordsL; i = step) {
let p = coords[i];
let [lat, lon] = [p[1], p[0]];
polygonPoints.push([lat, lon]);
}
return polygonPoints;
}
#map {
height: 90vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.8.0/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<h3>Query: London Downing street 10</h3>
<div id="map"></div>
可選:減少多邊形頂點
為了獲得更好的性能,您可能需要減少(通常是巨大的)頂點數量。
在遍歷 geoJson 坐標陣列時,您可能會像這樣洗掉坐標:
/**
* change coordinate order from [lon, lat] to [lat, lon]
* and reduce number of polygon vertices to 64
*/
function getGeoJsonPoly(coords, vertices=0, round=0){
let coordsL = coords.length;
let step = vertices!=0 ? Math.ceil(coordsL / vertices) : 1;
let polygonPoints = [];
for (let i = 0; i < coordsL; i = step) {
let p = coords[i];
let [lat, lon] = [p[1], p[0]];
if(round>0){
[lat, lon] = [ lat.toFixed(round), lat.toFixed(round)]
}
polygonPoints.push([lat, lon]);
}
return polygonPoints;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/492512.html
