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

一,逻辑

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

如下图所示:

图1,移动前只有视图内标记显示图1,移动前只有视图内标记显示

图2,移动后,新的视图内显示图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>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
OpenLayers是一个开源的JavaScript库,用于在Web上创建交互式地图应用程序。它提供了丰富的地图功能和丰富的API,使开发者能够轻松地呈现和操作地图数据。 对于海量点的显示,OpenLayers提供了几种方法来处理大量的标记点或矢量数据。以下是一些常用的技术: 1. 聚合:OpenLayers支持将多个密集的标记点聚合成一个单一的点。这可以减少在地图上绘制的要素数量,提高性能和可视化效果。您可以使用OpenLayers的聚合功能来实现这一点。 2. 分级显示:如果您有大量的标记点,可以使用分级显示来逐步加载和显示数据。您可以根据地图缩放级别调整标记点的显示数量和细节级别。这样可以避免一次性加载过多数据,从而提高性能。 3. 数据切片:如果您的数据集非常庞大,可以将数据进行切片处理,然后根据当前地图视图动态加载所需的数据切片。这种方法可以在保持性能的同时,提供对大量数据的浏览和查询能力。 4. 空间索引:使用空间索引技术,如四叉树或R树,可以对海量点数据进行高效的空间查询和过滤。这些索引可以帮助快速确定哪些点在给定的地理范围内,并进行相应的显示或处理。 请注意,处理海量点数据是一个复杂的问题,需要综合考虑性能、可视化效果和用户体验。具体的实现方法可能会因应用场景和需求而有所不同。以上提到的技术只是一些常见的方法,您可以根据具体情况选择合适的策略。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mf_717714

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值