效果
FeatureLayer和GeoJSONLayer, 一个矢量点同时渲染图形和文本
代码
相关参数自行查阅文档, 这里就不做注释了
示例代码手动创建FeatureLayer方式, 如果是通过远程url加载图层的 渲染方式同理, GeoJSONLayer同理
<!DOCTYPE html>
<html lang="zn">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
margin: 0;
}
#mapview {
position: absolute;
width: 100%;
height: 100%;
}
* {
margin: 0;
padding: 0;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.23/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.23/"></script>
</head>
<body>
<div id="mapview"></div>
<script>
require([
'esri/Map',
'esri/views/MapView',
'esri/layers/FeatureLayer',
'esri/Graphic'
], function (Map, MapView, FeatureLayer, Graphic) {
// 初始化底图
window.map = new Map({
basemap: 'dark-gray-vector'
})
// 创建2维视图
let view = new MapView({
container: 'mapview',
map: map,
zoom: 11,
center: [104.783916597735, 32.55699155692144] // 设置地图的初始化中心点坐标
})
// 生成100个随机点
var points = generateRandomPointsInPolygon(
[
[
[104.64487088240317, 32.66500681729125],
[104.91060269392625, 32.6635616904849],
[104.88210690535206, 32.54642886312837],
[104.68812954939528, 32.54787588095771]
]
],
100
)
// 创建feature点位
const features = points.map((point, index) => ({
geometry: {
type: 'point',
x: point[0],
y: point[1]
},
attributes: {
ObjectID: Math.random(),
name: `点${index + 1}`
}
}))
if (!features.length) {
return
}
console.log(features)
const featureLayer = new FeatureLayer({
source: features,
title: '生态因子点位图层',
objectIdField: 'ObjectID', // 重要, 必须
fields: [{ name: 'name', type: 'string' }],
outFields: ['*'],
popupTemplate: {
title: '{name}'
},
// 渲染成简单圆点
renderer: {
type: 'simple',
symbol: {
type: 'simple-marker',
color: 'red',
size: '10px',
outline: {
width: 1,
color: '#fff'
}
}
},
// 渲染额外的文本图形
labelingInfo: [
{
symbol: {
type: 'text',
color: '#fff',
// haloSize: 1,
// haloColor: '#fff',
backgroundColor: 'rgba(27,140,155,0.7)',
// xoffset: -22,
yoffset: 15,
horizontalAlignment: 'center',
font: { family: 'sans-serif', size: 8 }
},
labelPlacement: 'center-center',
labelExpressionInfo: { expression: '$feature.name' }
}
]
})
map.add(featureLayer)
// 添加点击
view.on('click', event => {
const { longitude, latitude } = event.mapPoint
// console.log('>>> 点击的坐标: ')
console.log(`${longitude}, ${latitude}`)
})
// 生成随机点
function generateRandomPointsInPolygon(polygonCoords, number) {
// 判断是否在图形内
function isPointInsidePolygon(point, polygonCoords) {
let crossings = 0
for (let i = 0, j = polygonCoords[0].length - 1; i < polygonCoords[0].length; j = i++) {
const xi = polygonCoords[0][i][0]
const yi = polygonCoords[0][i][1]
const xj = polygonCoords[0][j][0]
const yj = polygonCoords[0][j][1]
if (
((yi <= point[1] && point[1] < yj) || (yj <= point[1] && point[1] < yi)) &&
point[0] < ((xj - xi) * (point[1] - yi)) / (yj - yi) + xi
) {
crossings++
}
}
return crossings % 2 !== 0
}
// 存储生成的随机点
let randomPoints = []
// 获取多边形的最小和最大经纬度范围
let minLat = polygonCoords[0][0][1]
let maxLat = polygonCoords[0][0][1]
let minLng = polygonCoords[0][0][0]
let maxLng = polygonCoords[0][0][0]
for (let i = 0; i < polygonCoords[0].length; i++) {
const lat = polygonCoords[0][i][1]
const lng = polygonCoords[0][i][0]
if (lat < minLat) {
minLat = lat
}
if (lat > maxLat) {
maxLat = lat
}
if (lng < minLng) {
minLng = lng
}
if (lng > maxLng) {
maxLng = lng
}
}
for (let i = 0; i < number; i++) {
let isPointInside = false
let randomPoint
// 不断尝试生成随机点,直到点在多边形内
while (!isPointInside) {
// 在多边形的经纬度范围内随机生成一个点
const randomLat = minLat + (maxLat - minLat) * Math.random()
const randomLng = minLng + (maxLng - minLng) * Math.random()
randomPoint = [randomLng, randomLat]
// 使用射线法判断点是否在多边形内
isPointInside = isPointInsidePolygon(randomPoint, polygonCoords)
}
randomPoints.push(randomPoint)
}
return randomPoints
}
})
</script>
</body>
</html>