在 Next JS 中显示 arcgis 地图上多个坐标上的信息 Window
Display Info Window on the multiple coordinates on the arcgis map in Next JS
下面是我的下一个 JS 代码,它显示了一个简单的 ArcGIS 地图,其中包含特定坐标上的点或标记。
谁能告诉我如何显示地图上点的弹出窗口/信息 window?例如我点击任何一点,它会在上面打开一个相应的弹出窗口。
import NavBar from '@/components/NavBar'
import axios from 'axios';
import { useRef, useEffect, useState } from 'react';
import { loadModules } from 'esri-loader';
export default function Home({...props}) {
const [state, setState] = useState('');
const MapElement = useRef(null)
const options = {
url: 'https://js.arcgis.com/4.6/',
css: true
};
useEffect(() => {
var vehicleData = props.data
var map, point_symbol;
loadModules([
"esri/views/MapView",
"esri/WebMap",
"esri/Graphic",
"esri/geometry/Point",
"esri/PopupTemplate",
"esri/layers/FeatureLayer","dojo/domReady!"
],options).then(([ MapView, WebMap, Graphic, Point, PopupTemplate, FeatureLayer]) => {
const webmap = new WebMap({
basemap: "gray-vector"
})
var map = new MapView({
map: webmap,
center:[-6.357768833333333, 53.415487166666665],
zoom:6,
container: MapElement.current
})
map.popup.autoOpenEnabled = false;
for(var i=0, i_length=vehicleData.length; i<i_length; i++){
point_symbol = new Point({
longitude:vehicleData[i].longitude,
latitude: vehicleData[i].latitude,
spatialReference: { wkid: 3857 }
})
var template = new PopupTemplate({
title: vehicleData[i].company,
content: vehicleData[i].description
});
var graphic_symbol = new Graphic({
geometry: point_symbol,
symbol: {
type: "simple-marker",
style: "circle",
color: "orange",
size: "18px",
outline: {
color: [150, 200, 255],
width: 5
}
},
popupTemplate: template
});
map.graphics.add(graphic_symbol)
}
map.on("click", function(event) {
map.popup.open({
location: event.mapPoint,
features: [graphic_symbol]
});
});
// map.on("click", function(event) {
// console.log(vehicleData)
// map.popup.open({
// location: event.mapPoint, // location of the click on the view
// title: "You clicked here", // title displayed in the popup
// content: "Your description here" // content displayed in the popup
// });
// });
})
return () => {
if(!!map) {
map.destroy()
map=null
}
}
})
return (
<div id="home-container">
<NavBar />
<div className="app-wrapper" >
<div className="app-content">
<div className="no-padding">
<div className="row gy-4">
<div className="col-12">
<div style={{height:1000, width:1400}} ref={MapElement}></div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export async function getServerSideProps(context) {
let response = await axios(process.env.BASE_URL +'/devices/all',{
headers : {
'Authorization' : 'Bearer ' + process.env.TOKEN
}
})
let data = await response.data
return {
props : {
data: data
}
}
}
我需要显示与地图上每个标记多个圆相对应的弹出窗口或信息 window。在上面的代码中,API 调用是由 getServerSideProps
完成的,并且数据作为对象数组使用 props 传递给组件。
我可以在地图上显示多个圆圈,但不知道如何显示每个标记对应的信息window?
我认为在您的代码中变量 i
存在上下文问题。当弹出窗口显示 i
的值总是 vehicleData.length
.
所以你可以使用 let
而不是 var
来解决上下文问题,但我会建议你另一种方法。
在循环外声明弹出模板 template
,并使用我们将在下一步中添加的两个新属性。
var template = new PopupTemplate({
title: "{company}",
content: "{description}"
outFields: ["*"],
fieldInfos: [
{ fieldName: "company" },
{ fieldName: "description" }
]
});
将要显示的信息添加到图形的属性中,像这样,
var graphic_symbol = new Graphic({
geometry: point_symbol,
symbol: {
type: "simple-marker",
style: "circle",
color: "orange",
size: "18px",
outline: {
color: [150, 200, 255],
width: 5
}
},
popupTemplate: template,
attributes: { // <- here
company: vehicleData[i].company,
description: vehicleData[i].description
}
});
最后让点击事件搜索图形,像这样,
map.on("click", function(event) {
map.popup.open({
location: event.mapPoint,
fetchFeatures: true
});
});
顺便说一句,我只保留了最后一步,因为你故意更改默认值,我在这里没有看到原因,但你必须有一个。
@cabesuon 是对的。您可以删除点击事件并删除 map.popup.autoOpenEnabled = false;
。之后点击图形将默认打开弹出信息。
对于 table 格式,您可能希望对内容使用函数
// The following snippet shows how to use a function
// to create a simple node and display it in the popup template content
let template = new PopupTemplate({
title: "Population by Gender",
content: setContentInfo
});
function setContentInfo(feature){ // feature here is the graphic, you may access its properties for the table
// create a chart for example
let node = domConstruct.create("div", { innerHTML: "Text Element inside an HTML div element." });
return node;
}
下面是我的下一个 JS 代码,它显示了一个简单的 ArcGIS 地图,其中包含特定坐标上的点或标记。
谁能告诉我如何显示地图上点的弹出窗口/信息 window?例如我点击任何一点,它会在上面打开一个相应的弹出窗口。
import NavBar from '@/components/NavBar'
import axios from 'axios';
import { useRef, useEffect, useState } from 'react';
import { loadModules } from 'esri-loader';
export default function Home({...props}) {
const [state, setState] = useState('');
const MapElement = useRef(null)
const options = {
url: 'https://js.arcgis.com/4.6/',
css: true
};
useEffect(() => {
var vehicleData = props.data
var map, point_symbol;
loadModules([
"esri/views/MapView",
"esri/WebMap",
"esri/Graphic",
"esri/geometry/Point",
"esri/PopupTemplate",
"esri/layers/FeatureLayer","dojo/domReady!"
],options).then(([ MapView, WebMap, Graphic, Point, PopupTemplate, FeatureLayer]) => {
const webmap = new WebMap({
basemap: "gray-vector"
})
var map = new MapView({
map: webmap,
center:[-6.357768833333333, 53.415487166666665],
zoom:6,
container: MapElement.current
})
map.popup.autoOpenEnabled = false;
for(var i=0, i_length=vehicleData.length; i<i_length; i++){
point_symbol = new Point({
longitude:vehicleData[i].longitude,
latitude: vehicleData[i].latitude,
spatialReference: { wkid: 3857 }
})
var template = new PopupTemplate({
title: vehicleData[i].company,
content: vehicleData[i].description
});
var graphic_symbol = new Graphic({
geometry: point_symbol,
symbol: {
type: "simple-marker",
style: "circle",
color: "orange",
size: "18px",
outline: {
color: [150, 200, 255],
width: 5
}
},
popupTemplate: template
});
map.graphics.add(graphic_symbol)
}
map.on("click", function(event) {
map.popup.open({
location: event.mapPoint,
features: [graphic_symbol]
});
});
// map.on("click", function(event) {
// console.log(vehicleData)
// map.popup.open({
// location: event.mapPoint, // location of the click on the view
// title: "You clicked here", // title displayed in the popup
// content: "Your description here" // content displayed in the popup
// });
// });
})
return () => {
if(!!map) {
map.destroy()
map=null
}
}
})
return (
<div id="home-container">
<NavBar />
<div className="app-wrapper" >
<div className="app-content">
<div className="no-padding">
<div className="row gy-4">
<div className="col-12">
<div style={{height:1000, width:1400}} ref={MapElement}></div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export async function getServerSideProps(context) {
let response = await axios(process.env.BASE_URL +'/devices/all',{
headers : {
'Authorization' : 'Bearer ' + process.env.TOKEN
}
})
let data = await response.data
return {
props : {
data: data
}
}
}
我需要显示与地图上每个标记多个圆相对应的弹出窗口或信息 window。在上面的代码中,API 调用是由 getServerSideProps
完成的,并且数据作为对象数组使用 props 传递给组件。
我可以在地图上显示多个圆圈,但不知道如何显示每个标记对应的信息window?
我认为在您的代码中变量 i
存在上下文问题。当弹出窗口显示 i
的值总是 vehicleData.length
.
所以你可以使用 let
而不是 var
来解决上下文问题,但我会建议你另一种方法。
在循环外声明弹出模板 template
,并使用我们将在下一步中添加的两个新属性。
var template = new PopupTemplate({
title: "{company}",
content: "{description}"
outFields: ["*"],
fieldInfos: [
{ fieldName: "company" },
{ fieldName: "description" }
]
});
将要显示的信息添加到图形的属性中,像这样,
var graphic_symbol = new Graphic({
geometry: point_symbol,
symbol: {
type: "simple-marker",
style: "circle",
color: "orange",
size: "18px",
outline: {
color: [150, 200, 255],
width: 5
}
},
popupTemplate: template,
attributes: { // <- here
company: vehicleData[i].company,
description: vehicleData[i].description
}
});
最后让点击事件搜索图形,像这样,
map.on("click", function(event) {
map.popup.open({
location: event.mapPoint,
fetchFeatures: true
});
});
顺便说一句,我只保留了最后一步,因为你故意更改默认值,我在这里没有看到原因,但你必须有一个。
@cabesuon 是对的。您可以删除点击事件并删除 map.popup.autoOpenEnabled = false;
。之后点击图形将默认打开弹出信息。
对于 table 格式,您可能希望对内容使用函数
// The following snippet shows how to use a function
// to create a simple node and display it in the popup template content
let template = new PopupTemplate({
title: "Population by Gender",
content: setContentInfo
});
function setContentInfo(feature){ // feature here is the graphic, you may access its properties for the table
// create a chart for example
let node = domConstruct.create("div", { innerHTML: "Text Element inside an HTML div element." });
return node;
}