通过判断坐标是否在当前视图内,若在则显示,反之不显示。然后根据移动,放大或缩小地图,改变视图,展示新的点标记。
如下图所示:
视频
openlayers点标记只在视图内展示,视图外不展示
1,获取视图的范围
map.getView().calculateExtent()
2,获取坐标的标记的范围
feature.getGeometry().getExtent()
3,使用Style控制样式,来显示隐藏,如果在范围内给样式,不在样式为null
style: function(feature) {
return isTrue ? style : null
}
方式1
const layer = new ol.layer.Vector({
source: source,
style: function(feature) {
const calculateExtent = map.getView().calculateExtent();
const extent = feature.getGeometry().getExtent()
const isTrue = isInExtent(calculateExtent, extent)
return isTrue ? style : null
}
});
方式2
feature.setStyle(function(feature) {
const calculateExtent = map.getView().calculateExtent();
const extent = feature.getGeometry().getExtent()
const isTrue = isInExtent(calculateExtent, extent)
return isTrue ? style : null
})
判断点标记是否在范围内
function isInExtent(Extent, Point) {
return Extent[0] <= Point[0] && Point[0] <= Extent[2] && Extent[1] <= Point[1] && Point[1] <= Extent[3]
}
js文件和数据,自己造
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="./ol/ol.css">
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<style>
#map {
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<div id="map"></div>
</body>
</html>
<script src="./ol/ol.js"></script>
<script>
var projection = ol.proj.get("EPSG:4326");
var projectionExtent = projection.getExtent();
var size = ol.extent.getWidth(projectionExtent) / 256;
var resolutions = [];
for (var z = 2; z < 19; ++z) {
resolutions[z] = size / Math.pow(2, z);
}
const view = new ol.View({
zoom: 18,
maxZoom: 20,
minZoom: 5,
constrainResolution: true,
projection: "EPSG:4326",
center: [121.34906911986785, 28.484043198103166],
})
const map = new ol.Map({
// 绑定 DIV 元素
target: 'map',
// 添加图层
layers: [
// 设置图层的数据源
new ol.layer.Tile({
// 设置图层的数据源
source: new ol.source.XYZ({
url: "http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=2&scale=1&style=8",
})
}),
],
// 设置视图窗口
view,
});
// 绘制红色范围
const sourceExtent = new ol.source.Vector();
const layerExtent = new ol.layer.Vector({
source: sourceExtent
})
map.addLayer(layerExtent)
// 视图改变时,再次绘制范围
view.on('change', e => {
createExtentSource()
})
// 范围
function createExtentSource() {
const [x1, y1, x2, y2] = map.getView().calculateExtent();
const feature = new ol.Feature({
geometry: new ol.geom.Polygon.fromExtent([x1, y1, x2, y2])
});
feature.setStyle(
new ol.style.Style({
//边线颜色
stroke: new ol.style.Stroke({
color: 'red',
width: 2,
}),
})
)
sourceExtent.addFeature(feature);
}
// 数据
$.getJSON('./json/node.json', function(response) {
const nodes = response.data;
const geojsonObject = createGeoJson(nodes)
const source = new ol.source.Vector({
url: './json/GeoJson.json',
format: new ol.format.GeoJSON(),
});
const layer = new ol.layer.Vector({
source: source,
style: function(feature) {
const attributes = feature.getProperties()
const calculateExtent = map.getView().calculateExtent();
const extent = feature.getGeometry().getExtent()
const isTrue = isInExtent(calculateExtent, extent)
return isTrue ? createSourceStyle(`断面 | ${attributes.proName}`) : null
}
});
map.addLayer(layer)
})
// 判断点标记是否在范围内
function isInExtent(Extent, Point) {
return Extent[0] <= Point[0] && Point[0] <= Extent[2] && Extent[1] <= Point[1] && Point[1] <= Extent[3]
}
// 生产GeoJson数据
function createGeoJson(nodes) {
return {
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
},
"features": nodes.map(v => {
const {
longitude,
latitude
} = v;
return {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [longitude, latitude]
},
"properties": v
}
})
}
}
// 样式
function createSourceStyle(text) {
return new ol.style.Style({
text: new ol.style.Text({
text,
padding: [3, 10, 3, 10],
fill: new ol.style.Fill({
color: '#fff'
}),
backgroundFill: new ol.style.Fill({
color: '#2ea4fe'
}),
offsetY: -10
}),
image: new ol.style.RegularShape({
points: 3,
radius: 10,
rotation: Math.PI,
angle: 0,
fill: new ol.style.Fill({
color: '#2ea4fe'
})
}),
})
}
</script>