在某一个区县内,加载不同的类型的坐标点,并用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_.name
console.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_.name
console.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