openlayer:12在某一区县内(一定区域内)加载不同类型的坐标位置,点击后弹出overlay弹窗显示坐标点详细信息,点击弹窗上关闭按钮关闭弹窗
在某一个区县内,加载不同的类型的坐标点,并用image的颜色进行区分这些坐标点的类型。点击不同颜色的坐标点,提示出相关坐标点的具体信息。
本文介绍了如何使用OpenLayers在区县地图上加载不同颜色的坐标点,并通过点击展示详细信息。首先设置地图视图和天地图底图,然后创建三种颜色的坐标点图层(黄、红、绿),分别用不同图标表示。绿色坐标点还包含名称、省市区等属性信息。通过添加点击事件监听,当用户点击绿色点时,会弹出信息框显示该点的详细属性数据。实现过程包括:创建矢量图层、设置点样式、绑定点击事件、处理特征属性等。通过forEachFeatureAtPixel方法获取点击位置的特征信息;4)使用Overlay实现弹窗功能,动态显示所选点的详细信息。
一、解释
let map=null;
let popup=null;
设置全局map和popup弹窗
const [name,setname]=useState('')const [prov,setprov]=useState('')const [city,setcity]=useState('')const [distr,setdistr]=useState('')
设置state数据,用来动态显示在div中
let view=new View({center:fromLonLat([123.464679, 41.677586]),zoom:9,})
设置中心点和view视图let ditulayer=new TileLayer({source:new XYZ({url :"http://t5.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=528881a2c3d647268c04ab43dc46bd51"})})let biaojilayer=new TileLayer({source:new XYZ({url :"http://t3.tianditu.com/DataServer?T=cva_w&tk=faf4cf166d31edcaba5de523eae8084f&x={x}&y={y}&l={z}"})})
设置底图图层和注记图层let vectorlayer=new VectorLayer({source:new VectorSource({url:"https://geo.datav.aliyun.com/areas_v3/bound/210100.json",format:new GeoJSON()}),style:new Style({fill:new Fill({color:"rgba(0,96,255,0.2)"}),stroke:new Stroke({color:'#0060ff',width:3})})})
设置矢量图层并给出样式(数据源看我之前文章即可,数据格式是GeoJSON格式)
let yellowsource=new VectorSource({})let yellowlayer=new VectorLayer({source:yellowsource})let yellowpoints=[fromLonLat([123.464679, 41.677586]),fromLonLat([123.33, 41.67]),fromLonLat([122.82283, 41.99203899])]yellowpoints.forEach(function(coords){let yellowfeature = new Feature({geometry: new Point(coords),});yellowfeature.setStyle(new Style({image:new Icon({src:yellow,})}))yellowsource.addFeature(yellowfeature); })创建黄色的坐标点,并将坐标点用黄色的图片来代替位置坐标
let redsource=new VectorSource({})let redlayer=new VectorLayer({source:redsource})let redpoints=[fromLonLat([123.249151,41.748329]),fromLonLat([123.584281, 41.913100])]redpoints.forEach(function(coords){let redfeature = new Feature({geometry: new Point(coords),});redfeature.setStyle(new Style({image:new Icon({src:red,})}))redsource.addFeature(redfeature); })创建蓝色的坐标点,并将坐标点用蓝色的图片来代替位置坐标
const greenList=[{lonlat:[123.184471, 42.342171],name:"丁家房镇",prov:"辽宁",city:"沈阳",distr:"法库"},{lonlat:[123.370625,41.852098],name:"梁山镇",prov:"辽宁",city:"沈阳",distr:"新民"},{lonlat:[123.370625,41.852098],name:"梁山镇",prov:"辽宁",city:"沈阳",distr:"新民"},]const greensource=new VectorSource({})const greenlayer=new VectorLayer({source:greensource})greenList.forEach(function(item){let greenfeature = new Feature({geometry: new Point(fromLonLat(item.lonlat)),name: item.name,});greenfeature.setStyle(new Style({image:new Icon({src:green,})}))greensource.addFeature(greenfeature); })创建绿色的坐标点,并将坐标点用绿色的图片来代替位置坐标
popup=new Overlay({element:document.getElementById("popup"),})map.addOverlay(popup)获取id为popup的div
并将其添加到map中map.on('singleclick', function(evt) {map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {if (layer === greenlayer) {console.log('Clicked on the vector layer');let pixel=evt.pixel;console.log(pixel)let features=map.getFeaturesAtPixel(pixel);console.log(features[0])let selectname=features[0].values_.nameconsole.log(selectname)let geometry = features[0].getGeometry().getCoordinates();console.log(geometry)greenList.map((item,index)=>{if(item.name==selectname){setname(item.name);setcity(item.city)setprov(item.prov)setdistr(item.distr)}})popup.setPosition(geometry);map.addOverlay(popup);}else{console.log('Clicked on the tile layer');}});});
为map添加点击事件
利用forEachFeatureAtPixel方法,获取屏幕位置,feature特性和layer图层
二、完整代码
import { useState ,useEffect} from 'react';
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import XYZ from 'ol/source/XYZ.js';
import VectorLayer from 'ol/layer/Vector.js';
import VectorSource from 'ol/source/Vector.js';
import GeoJSON from 'ol/format/GeoJSON.js';
import Style from 'ol/style/Style.js';
import Fill from 'ol/style/Fill.js';
import Stroke from 'ol/style/Stroke.js';
import Icon from 'ol/style/Icon.js';
import Feature from 'ol/Feature.js';
import Polygon from 'ol/geom/Polygon.js';
import Point from 'ol/geom/Point.js';
import Overlay from 'ol/Overlay.js';
import {fromLonLat} from 'ol/proj';
import './System.css'
import 'ol/ol.css';
import yellow from '../../assets/yellow.png';
import red from '../../assets/red.png';
import green from '../../assets/green.png';
import close from '../../assets/close.png';
let map=null;
let popup=null;
function System() {const [name,setname]=useState('')const [prov,setprov]=useState('')const [city,setcity]=useState('')const [distr,setdistr]=useState('')let view=new View({center:fromLonLat([123.464679, 41.677586]),zoom:9,})let ditulayer=new TileLayer({source:new XYZ({url :"http://t5.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=528881a2c3d647268c04ab43dc46bd51"})})let biaojilayer=new TileLayer({source:new XYZ({url :"http://t3.tianditu.com/DataServer?T=cva_w&tk=faf4cf166d31edcaba5de523eae8084f&x={x}&y={y}&l={z}"})})let vectorlayer=new VectorLayer({source:new VectorSource({url:"https://geo.datav.aliyun.com/areas_v3/bound/210100.json",format:new GeoJSON()}),style:new Style({fill:new Fill({color:"rgba(0,96,255,0.2)"}),stroke:new Stroke({color:'#0060ff',width:3})})})let yellowsource=new VectorSource({})let yellowlayer=new VectorLayer({source:yellowsource})let yellowpoints=[fromLonLat([123.464679, 41.677586]),fromLonLat([123.33, 41.67]),fromLonLat([122.82283, 41.99203899])]yellowpoints.forEach(function(coords){let yellowfeature = new Feature({geometry: new Point(coords),});yellowfeature.setStyle(new Style({image:new Icon({src:yellow,})}))yellowsource.addFeature(yellowfeature); })let redsource=new VectorSource({})let redlayer=new VectorLayer({source:redsource})let redpoints=[fromLonLat([123.249151,41.748329]),fromLonLat([123.584281, 41.913100])]redpoints.forEach(function(coords){let redfeature = new Feature({geometry: new Point(coords),});redfeature.setStyle(new Style({image:new Icon({src:red,})}))redsource.addFeature(redfeature); })const greenList=[{lonlat:[123.184471, 42.342171],name:"丁家房镇",prov:"辽宁",city:"沈阳",distr:"法库"},{lonlat:[123.370625,41.852098],name:"梁山镇",prov:"辽宁",city:"沈阳",distr:"新民"},{lonlat:[123.370625,41.852098],name:"梁山镇",prov:"辽宁",city:"沈阳",distr:"新民"},]const greensource=new VectorSource({})const greenlayer=new VectorLayer({source:greensource})greenList.forEach(function(item){let greenfeature = new Feature({geometry: new Point(fromLonLat(item.lonlat)),name: item.name,});greenfeature.setStyle(new Style({image:new Icon({src:green,})}))greensource.addFeature(greenfeature); })useEffect(()=>{map=new Map({target:"mapp",view:view,layers:[ditulayer,biaojilayer,vectorlayer,yellowlayer,redlayer,greenlayer]})popup=new Overlay({element:document.getElementById("popup"),})map.addOverlay(popup)map.on('singleclick', function(evt) {map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {if (layer === greenlayer) {console.log('Clicked on the vector layer');let pixel=evt.pixel;console.log(pixel)let features=map.getFeaturesAtPixel(pixel);console.log(features[0])let selectname=features[0].values_.nameconsole.log(selectname)let geometry = features[0].getGeometry().getCoordinates();console.log(geometry)greenList.map((item,index)=>{if(item.name==selectname){setname(item.name);setcity(item.city)setprov(item.prov)setdistr(item.distr)}})popup.setPosition(geometry);map.addOverlay(popup);}else{console.log('Clicked on the tile layer');}});});},[])function closeTag(){popup.setPosition(undefined);}return (<><div id="mapp" style={{width: "100%",height: "97vh"}}><div id="popup"><div className="row_title"><span>信息如下:</span><img className="row_title_img" src={close} onClick={closeTag}/></div><div className="row_content"><div>名称:{name}</div><div>省份:{prov}</div><div>城市:{city}</div><div>区县:{distr}</div></div></div></div></>)
}export default System