L.CRS.Simple 传单最低缩放级别仍然太高
Leaflet lowest zoom level is still too high with L.CRS.Simple
试图检索区域的一部分,但由于某种原因无法看到整个区域,即使缩放级别为 0,(据说)我们应该看到整个世界。
我正在使用 L.CRS.Simple 因为它使用 EPSG:3763 并且在 CRS 列表中看不到那个。我正在检索 JSON 中的数据,因为在绑定 geoJSON 时,无法将 3D 坐标数据转换为 2D 平面数据。
const queryRegionText = "where=OBJECTID > 0"
const geoJsonURL2 = "https://sig.cm-figfoz.pt/arcgis/rest/services/Internet/MunisigWeb_DadosContexto/MapServer/2/query?f=json&returnGeometry=true&geometryType=esriGeometryPolyline&spatialRel=esriSpatialRelIntersects&outFields=*&outSR=3763&" + queryRegionText
var map = L.map('mapid', {
crs: L.CRS.Simple
}).setView([-58216.458338, 42768.347232], 0);
L.control.scale({ metric: true }).addTo(map);
fetch(geoJsonURL2).then(function (response) {
response.json().then(function (data) {
data.features.forEach(element => {
if (element.geometry.rings) {
element.geometry.rings.forEach(point => {
L.polyline(point, { color: 'red' }).addTo(map);
})
}
});
});
});
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
map.on('click', onMapClick);
<html>
<head>
<title>Leaflet - testing</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
</head>
<body>
<div id="mapid" style="width: 600px; height: 400px;"></div>
</body>
</html>
TL;DR: 创建地图时,将最小缩放比例设置为零以下。这应该有效:
var map = L.map('mapid', {
crs: L.CRS.Simple, minZoom: -6
}).setView([-57728, 55296], -6);
说明
通常,Leaflet 从 latitude/longitude 坐标系转换为屏幕像素,假设世界在缩放级别 0 时为 256 像素高。在每个更高的缩放级别,像素数量加倍(解释得很好在 Zoom levels tutorial) 中。有了这个假设,地图的选项默认为 {minZoom: 0, maxZoom: Infinity}
(因为您没有添加任何将这些值设置为任何不同的图层)。
当您使用 L.CRS.Simple
时,在缩放级别 0 时,它会将 1 个坐标单位映射到 1 个屏幕像素。您的数据看起来大约有 18000 个坐标单位高,因此它不适合您的 400 像素高的地图。为了使其适合,我们需要每个屏幕像素映射到大约 45 个坐标单位。 2^5 是 32,2^6 是 64,所以我们需要缩小 5 到 6 倍。幸运的是,Leaflet 接受负缩放级别,因此将缩放设置为 -6 就可以了。但要使其正常工作,您需要设置 {minZoom: -6}
,这样地图就不会卡在缩放级别 0。Non-geographical Maps tutorial.
中有一个很好的示例
使用 L.CRS.Simple
应该适合您,只要近似值认为每个纬度单位与每个经度单位(正方形世界)的长度相同。由于这在现实世界中通常不是真的,因此使用简单投影会导致一些失真。如果失真对于您感兴趣的功能很重要,那么您将需要按照@IvanSanchez 的建议,使用 L.CRS
和 Proj4Leaflet 来查找如何正确使用 EPSG:3763。
所以,在阅读了 proj4leaflet 之后,提出了这段代码。提前感谢以上评论和回复。
const queryRegionText = "where=OBJECTID > 0"
const geoJsonURL2 = "https://sig.cm-figfoz.pt/arcgis/rest/services/Internet/MunisigWeb_DadosContexto/MapServer/2/query?f=geojson&returnGeometry=true&geometryType=esriGeometryPolyline&spatialRel=esriSpatialRelIntersects&outFields=*&outSR=3763&" + queryRegionText
const map = L.map('map', {
center: [40.14791, -8.87009],
zoom: 13
});
proj4.defs("EPSG:3763", "+proj=tmerc +lat_0=39.66825833333333 +lon_0=-8.133108333333334 +k=1 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs");
fetch(geoJsonURL2).then(function (response) {
response.json().then(function (data) {
L.Proj.geoJson(data).addTo(map);
});
});
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
map.on('click', onMapClick);
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<link rel="stylesheet" href="main.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.7.4/proj4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4leaflet/1.0.2/proj4leaflet.js"></script>
</head>
<body class="">
<div id="map" style="width: 600px; height: 400px;"></div>
</div>
<script src="main.js"></script>
</body>
试图检索区域的一部分,但由于某种原因无法看到整个区域,即使缩放级别为 0,(据说)我们应该看到整个世界。 我正在使用 L.CRS.Simple 因为它使用 EPSG:3763 并且在 CRS 列表中看不到那个。我正在检索 JSON 中的数据,因为在绑定 geoJSON 时,无法将 3D 坐标数据转换为 2D 平面数据。
const queryRegionText = "where=OBJECTID > 0"
const geoJsonURL2 = "https://sig.cm-figfoz.pt/arcgis/rest/services/Internet/MunisigWeb_DadosContexto/MapServer/2/query?f=json&returnGeometry=true&geometryType=esriGeometryPolyline&spatialRel=esriSpatialRelIntersects&outFields=*&outSR=3763&" + queryRegionText
var map = L.map('mapid', {
crs: L.CRS.Simple
}).setView([-58216.458338, 42768.347232], 0);
L.control.scale({ metric: true }).addTo(map);
fetch(geoJsonURL2).then(function (response) {
response.json().then(function (data) {
data.features.forEach(element => {
if (element.geometry.rings) {
element.geometry.rings.forEach(point => {
L.polyline(point, { color: 'red' }).addTo(map);
})
}
});
});
});
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
map.on('click', onMapClick);
<html>
<head>
<title>Leaflet - testing</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
</head>
<body>
<div id="mapid" style="width: 600px; height: 400px;"></div>
</body>
</html>
TL;DR: 创建地图时,将最小缩放比例设置为零以下。这应该有效:
var map = L.map('mapid', {
crs: L.CRS.Simple, minZoom: -6
}).setView([-57728, 55296], -6);
说明
通常,Leaflet 从 latitude/longitude 坐标系转换为屏幕像素,假设世界在缩放级别 0 时为 256 像素高。在每个更高的缩放级别,像素数量加倍(解释得很好在 Zoom levels tutorial) 中。有了这个假设,地图的选项默认为 {minZoom: 0, maxZoom: Infinity}
(因为您没有添加任何将这些值设置为任何不同的图层)。
当您使用 L.CRS.Simple
时,在缩放级别 0 时,它会将 1 个坐标单位映射到 1 个屏幕像素。您的数据看起来大约有 18000 个坐标单位高,因此它不适合您的 400 像素高的地图。为了使其适合,我们需要每个屏幕像素映射到大约 45 个坐标单位。 2^5 是 32,2^6 是 64,所以我们需要缩小 5 到 6 倍。幸运的是,Leaflet 接受负缩放级别,因此将缩放设置为 -6 就可以了。但要使其正常工作,您需要设置 {minZoom: -6}
,这样地图就不会卡在缩放级别 0。Non-geographical Maps tutorial.
使用 L.CRS.Simple
应该适合您,只要近似值认为每个纬度单位与每个经度单位(正方形世界)的长度相同。由于这在现实世界中通常不是真的,因此使用简单投影会导致一些失真。如果失真对于您感兴趣的功能很重要,那么您将需要按照@IvanSanchez 的建议,使用 L.CRS
和 Proj4Leaflet 来查找如何正确使用 EPSG:3763。
所以,在阅读了 proj4leaflet 之后,提出了这段代码。提前感谢以上评论和回复。
const queryRegionText = "where=OBJECTID > 0"
const geoJsonURL2 = "https://sig.cm-figfoz.pt/arcgis/rest/services/Internet/MunisigWeb_DadosContexto/MapServer/2/query?f=geojson&returnGeometry=true&geometryType=esriGeometryPolyline&spatialRel=esriSpatialRelIntersects&outFields=*&outSR=3763&" + queryRegionText
const map = L.map('map', {
center: [40.14791, -8.87009],
zoom: 13
});
proj4.defs("EPSG:3763", "+proj=tmerc +lat_0=39.66825833333333 +lon_0=-8.133108333333334 +k=1 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs");
fetch(geoJsonURL2).then(function (response) {
response.json().then(function (data) {
L.Proj.geoJson(data).addTo(map);
});
});
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
map.on('click', onMapClick);
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<link rel="stylesheet" href="main.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.7.4/proj4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4leaflet/1.0.2/proj4leaflet.js"></script>
</head>
<body class="">
<div id="map" style="width: 600px; height: 400px;"></div>
</div>
<script src="main.js"></script>
</body>