-1

下面是我的下一个 JS 代码,它显示了一个简单的 ArcGIS 地图,其中包含特定坐标上的点或标记。

谁能告诉我如何显示地图上点的弹出/信息窗口?例如,我点击任何一点,它会在上面打开一个相应的弹出窗口。

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
        }
    }
}

我需要在地图上显示与每个标记多个圆圈相对应的弹出窗口或信息窗口。在上面的代码中,API 调用由 完成getServerSideProps,数据作为对象数组通过 props 传递给组件。

我可以在地图上显示多个圆圈,但不知道如何显示与每个标记对应的信息窗口?

在此处输入图像描述

4

2 回答 2

3

我认为在您的代码中,您的变量存在上下文问题i。当弹出窗口显示ialways gonna be的值时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
    });
});

顺便说一句,我只保留最后一步,因为您故意更改默认值,我在这里看不到原因,但您必须有一个。

于 2021-10-20T20:19:14.627 回答
1

@cabesuon 是对的。您可以删除点击事件并删除map.popup.autoOpenEnabled = false;。之后单击图形将默认打开弹出信息。

对于表格格式,您可能希望对内容使用功能

    // 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;
    }

于 2021-10-21T04:59:02.767 回答