openlayers点标记只在视图内展示,视图外不展示,用于大量数据展示

一,逻辑

通过判断坐标是否在当前视图内,若在则显示,反之不显示。然后根据移动,放大或缩小地图,改变视图,展示新的点标记。

如下图所示:

图1,移动前只有视图内标记显示openlayers点标记只在视图内展示,视图外不展示,用于大量数据展示_第1张图片

图2,移动后,新的视图内显示openlayers点标记只在视图内展示,视图外不展示,用于大量数据展示_第2张图片

视频

openlayers点标记只在视图内展示,视图外不展示

二,使用的API

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>

你可能感兴趣的:(openlayers,javascript,openlayers,大量数据)