ESRI ArcGIS:平移和缩放以适合标记
ESRI ArcGIS: Pan and Zoom to fit markers
我是 ESRI ArcGIS 的新手。我们正在考虑替代 Google 地图。在此 post https://www.esri.com/arcgis-blog/products/js-api-arcgis/announcements/migrating-from-google-maps-javascript-api-to-arcgis-api-for-javascript/ 中,他们解释了迁移到 ArcGIS 应该是多么容易,但似乎超出了他们提供的示例,我被卡住了。
我在地图中加载了一堆标记。我正在尝试让地图平移和缩放以适合所有标记,但我一直无法找到执行此操作的任何代码。
在 Google 地图上我会这样做:
myMap.options.center = new google.maps.LatLng(0,0);
myMap.options.mapTypeId = google.maps.MapTypeId[myMap.options.mapTypeId];
myMap.bounds = new google.maps.LatLngBounds();
myMap.map = new google.maps.Map(document.getElementById('cat-map'), myMap.options);
google.maps.event.addListenerOnce(myMap.map, 'bounds_changed', function(event){
myMap.map.fitBounds(myMap.bounds);
myMap.map.panToBounds(myMap.bounds);
});
for (var i = 0; i < myMap.items.length; i++) {
var itemLatlng = new google.maps.LatLng(myMap.items[i].lat, myMap.items[i].lng);
myMap.bounds.extend(itemLatlng);
new google.maps.Marker({
position: itemLatlng,
map: myMap.map,
});
}
但我一直无法在 ESRI ArcGIS 上找到等效项。
有人指导一下吗?
你的想法是对的。在 ArcGIS 中,API Extent
class 具有 union
扩展调用方以将几何范围传递作为参数包含在内的方法。因为您正在使用 Point
不能使用 union
方法,Point
范围是 null
。但不用担心,您只需自己迭代图形并扩展范围就可以实现这一目标。
看看我为你做的这个例子,使用你问题的 link 作为基础,
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>ArcGIS API for JavaScript Hello World App</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#zoomBtn {
margin: .5rem;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.15/esri/css/main.css">
<script src="https://js.arcgis.com/4.15/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
'esri/geometry/Extent'
], function (Map, MapView, Extent) {
const map = new Map({
basemap: "streets-navigation-vector"
});
const view = new MapView({
container: "viewDiv",
map: map,
zoom: 12,
center: {
latitude: 32.7353,
longitude: -117.1490
}
});
function popupContent (feature) {
const div = document.createElement("div");
div.innerHTML = `Address: ${feature.graphic.attributes.addrs} <br>` +
`<a href='${feature.graphic.attributes.url}'>Web</a>`;
return div;
}
function toGraphic(color, lon, lat, title, addrs, url) {
return {
symbol: {
type: "text",
color,
text: "\ue61d",
font: {
size: 30,
family: "CalciteWebCoreIcons"
}
},
geometry: {
type: "point",
longitude: lon,
latitude: lat
},
attributes: {
title,
addrs,
url
},
popupTemplate: {
title: '{title}',
outfields: ['*'],
content: popupContent
}
}
}
const graphics = [
toGraphic(
'gray',
-117.1560632,
32.727482,
'Automotive Museum',
'2080 Pan American Plaza, San Diego, CA 92101, United States',
'http://sdautomuseum.org/'
),
toGraphic(
'gray',
-117.1763293,
32.7136902,
'USS Midway Museum',
'910 N Harbor Dr, San Diego, CA 92101, United States',
'http://www.midway.org/'
),
toGraphic(
'blue',
-117.2284536,
32.7641112,
'SeaWorld',
'500 Sea World Dr, San Diego, CA 92109, United States',
'https://seaworld.com/san-diego'
),
toGraphic(
'green',
-117.1557741,
32.7360032,
'Zoo',
'2920 Zoo Dr, San Diego, CA 92101, United States',
'https://zoo.sandiegozoo.org/'
)
];
view.graphics.addMany(graphics);
function maxExtent(graphics) {
const e = graphics
.map(g => g.geometry)
.reduce(
(acc, geom) => (
{
xmin: Math.min(acc.xmin, geom.longitude),
ymin: Math.min(acc.ymin, geom.latitude),
xmax: Math.max(acc.xmax, geom.longitude),
ymax: Math.max(acc.ymax, geom.latitude)
}
),
{
xmin: Number.MAX_SAFE_INTEGER,
ymin: Number.MAX_SAFE_INTEGER,
xmax: Number.MIN_SAFE_INTEGER,
ymax: Number.MIN_SAFE_INTEGER
}
);
return new Extent(e);
}
document.getElementById('zoomBtn')
.addEventListener(
'click',
_ => {
const ext = maxExtent(graphics);
console.log(`View Extent: ${JSON.stringify(view.extent)} Graphics Extent:${JSON.stringify(ext)}`);
view.extent = ext.expand(2); // expand a little so border points shows
}
);
});
</script>
</head>
<body>
<div class="esri-widget">
<button id="zoomBtn" class="esri-button">Zoom To Graphics</button>
</div>
<div id="viewDiv"></div>
</body>
</html>
我是 ESRI ArcGIS 的新手。我们正在考虑替代 Google 地图。在此 post https://www.esri.com/arcgis-blog/products/js-api-arcgis/announcements/migrating-from-google-maps-javascript-api-to-arcgis-api-for-javascript/ 中,他们解释了迁移到 ArcGIS 应该是多么容易,但似乎超出了他们提供的示例,我被卡住了。
我在地图中加载了一堆标记。我正在尝试让地图平移和缩放以适合所有标记,但我一直无法找到执行此操作的任何代码。
在 Google 地图上我会这样做:
myMap.options.center = new google.maps.LatLng(0,0);
myMap.options.mapTypeId = google.maps.MapTypeId[myMap.options.mapTypeId];
myMap.bounds = new google.maps.LatLngBounds();
myMap.map = new google.maps.Map(document.getElementById('cat-map'), myMap.options);
google.maps.event.addListenerOnce(myMap.map, 'bounds_changed', function(event){
myMap.map.fitBounds(myMap.bounds);
myMap.map.panToBounds(myMap.bounds);
});
for (var i = 0; i < myMap.items.length; i++) {
var itemLatlng = new google.maps.LatLng(myMap.items[i].lat, myMap.items[i].lng);
myMap.bounds.extend(itemLatlng);
new google.maps.Marker({
position: itemLatlng,
map: myMap.map,
});
}
但我一直无法在 ESRI ArcGIS 上找到等效项。
有人指导一下吗?
你的想法是对的。在 ArcGIS 中,API Extent
class 具有 union
扩展调用方以将几何范围传递作为参数包含在内的方法。因为您正在使用 Point
不能使用 union
方法,Point
范围是 null
。但不用担心,您只需自己迭代图形并扩展范围就可以实现这一目标。
看看我为你做的这个例子,使用你问题的 link 作为基础,
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>ArcGIS API for JavaScript Hello World App</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#zoomBtn {
margin: .5rem;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.15/esri/css/main.css">
<script src="https://js.arcgis.com/4.15/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
'esri/geometry/Extent'
], function (Map, MapView, Extent) {
const map = new Map({
basemap: "streets-navigation-vector"
});
const view = new MapView({
container: "viewDiv",
map: map,
zoom: 12,
center: {
latitude: 32.7353,
longitude: -117.1490
}
});
function popupContent (feature) {
const div = document.createElement("div");
div.innerHTML = `Address: ${feature.graphic.attributes.addrs} <br>` +
`<a href='${feature.graphic.attributes.url}'>Web</a>`;
return div;
}
function toGraphic(color, lon, lat, title, addrs, url) {
return {
symbol: {
type: "text",
color,
text: "\ue61d",
font: {
size: 30,
family: "CalciteWebCoreIcons"
}
},
geometry: {
type: "point",
longitude: lon,
latitude: lat
},
attributes: {
title,
addrs,
url
},
popupTemplate: {
title: '{title}',
outfields: ['*'],
content: popupContent
}
}
}
const graphics = [
toGraphic(
'gray',
-117.1560632,
32.727482,
'Automotive Museum',
'2080 Pan American Plaza, San Diego, CA 92101, United States',
'http://sdautomuseum.org/'
),
toGraphic(
'gray',
-117.1763293,
32.7136902,
'USS Midway Museum',
'910 N Harbor Dr, San Diego, CA 92101, United States',
'http://www.midway.org/'
),
toGraphic(
'blue',
-117.2284536,
32.7641112,
'SeaWorld',
'500 Sea World Dr, San Diego, CA 92109, United States',
'https://seaworld.com/san-diego'
),
toGraphic(
'green',
-117.1557741,
32.7360032,
'Zoo',
'2920 Zoo Dr, San Diego, CA 92101, United States',
'https://zoo.sandiegozoo.org/'
)
];
view.graphics.addMany(graphics);
function maxExtent(graphics) {
const e = graphics
.map(g => g.geometry)
.reduce(
(acc, geom) => (
{
xmin: Math.min(acc.xmin, geom.longitude),
ymin: Math.min(acc.ymin, geom.latitude),
xmax: Math.max(acc.xmax, geom.longitude),
ymax: Math.max(acc.ymax, geom.latitude)
}
),
{
xmin: Number.MAX_SAFE_INTEGER,
ymin: Number.MAX_SAFE_INTEGER,
xmax: Number.MIN_SAFE_INTEGER,
ymax: Number.MIN_SAFE_INTEGER
}
);
return new Extent(e);
}
document.getElementById('zoomBtn')
.addEventListener(
'click',
_ => {
const ext = maxExtent(graphics);
console.log(`View Extent: ${JSON.stringify(view.extent)} Graphics Extent:${JSON.stringify(ext)}`);
view.extent = ext.expand(2); // expand a little so border points shows
}
);
});
</script>
</head>
<body>
<div class="esri-widget">
<button id="zoomBtn" class="esri-button">Zoom To Graphics</button>
</div>
<div id="viewDiv"></div>
</body>
</html>