openlayers - 在 Openlayers 中,如何根据相同坐标通过的次数来缩放 MultiLineString 的笔划宽度?
问题描述
我的 MultiLineString 目前的样式如下:
'MultiLineString': new Style({
stroke: new Stroke({
color: 'green',
width: 1
})
}),
我的 MultiLineString 的坐标看起来像这样:
[
[[3, 8], [4, 10], [5, 12]],
[[2, 4], [3, 8], [4, 10]]
]
数据中有一些重叠的地方。我想缩放数据重叠的线的宽度,以帮助说明该线被多次遍历。我猜我需要使用RenderFunction(),但我很难理解下一步该做什么。
任何帮助将不胜感激。
解决方案
是的,可以使用 Turf 完成,但 Turf 仅适用于 EPSG:4326 坐标,并且 EPSG:4326 中的重叠部分在 EPSG:3857 中显示时不一定重叠,反之亦然,例如 [[0,50],[5 ,55],[10,60]] 在转换为 EPSG:3857 时不是一条直线,而 [[0,50],[10,60]] 是。变换还引入了非常小的舍入差异。虽然非常小,但任何差异都会阻止检测到重叠(并且使用 Turf 的 km 容差设置可能会产生误报)。此示例进行了额外的迭代,并向 MultiLineString 添加了一个额外的组件,以测试较长线段的顶点之间的交点。在四舍五入到 12 个位置后,在 EPSG:4326 中检测到重叠(即使是真实世界的小数值,这也可能不起作用),但如果你放大到足够大,你可以看到它是 EPSG 中的一条平行线:
var transformR = function(coordinates, output, dimensions) {
var dims = dimensions || 2;
for (var i=0; i<coordinates.length; i+=dims) {
coordinates[i] = Math.round(coordinates[i]*1e12)/1e12;
coordinates[i+1] = Math.round(coordinates[i+1]*1e12)/1e12;
}
return coordinates;
}
var style = function(feature) {
switch(feature.getGeometry().getType()) {
case 'MultiLineString':
var increment = 2;
var styles = [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'green',
width: increment
})
})
];
var overlaps = [];
var format = new ol.format.GeoJSON();
var geometry = feature.getGeometry().clone().transform(map.getView().getProjection(), 'EPSG:4326');
geometry.applyTransform(transformR); // round transformed coordinates
var linestrings = geometry.getLineStrings();
for (var i=0; i<linestrings.length-1; i++) {
for (var j=i+1; j<linestrings.length; j++) {
var line1 = format.writeFeatureObject(new ol.Feature(linestrings[i]));
var line2 = format.writeFeatureObject(new ol.Feature(linestrings[j]));
var overlapping = turf.lineOverlap(line1, line2).features;
overlapping.forEach(function(overlap){ overlaps.push(overlap.geometry.coordinates); });
}
}
overlaps.forEach(function(overlap){
var width = increment;
var line = turf.lineString(overlap);
for (var i=0; i<linestrings.length; i++) {
var line1 = format.writeFeatureObject(new ol.Feature(linestrings[i]));
var overlapping = turf.lineOverlap(line, line1).features;
if (overlapping.length > 0 && JSON.stringify(overlapping[0].geometry.coordinates) == JSON.stringify(overlap)) {
width += increment;
}
}
styles.push(
new ol.style.Style({
geometry: new ol.geom.LineString(overlap).transform('EPSG:4326', map.getView().getProjection()),
stroke: new ol.style.Stroke({
color: 'green',
width: width
})
})
);
});
return styles;
}
}
var multiline = new ol.Feature(new ol.geom.MultiLineString([
[[6, 14], [2, 6]],
[[3, 8], [4, 10], [5, 12]],
[[2, 4], [3, 8], [4, 10]]
]));
var source = new ol.source.Vector();
var map = new ol.Map({
layers: [
new ol.layer.Vector({
source: source,
style: style
})
],
target: 'map',
view: new ol.View()
});
multiline.getGeometry().transform('EPSG:4326', map.getView().getProjection());
source.addFeature(multiline);
map.getView().fit(multiline.getGeometry());
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<script src="https://npmcdn.com/@turf/turf@5.1.6/turf.min.js"></script>
<div id="map" class="map"></div>
推荐阅读
- php - 将文章插入数据库时遇到问题 Laravel 8
- ios - 有没有办法在 Swift 中弃用或隐藏系统框架 API?
- wordpress - 是否可以使用 Google Translate API 或其他工具在 wordpress 中翻译实时提要?
- amazon-web-services - 使用 AWS Beanstalk 的 Graylog
- reactjs - Material-UI:使用字符和长度限制reactjs更新期间无法删除TextField中的数据
- c++ - 在 Cpp for 中无法从函数中正常工作
- zoomcharts - NetChart replaceData() 显示空白。如何动态替换数据?
- c++ - Unordered_map 奇怪的字符
- kotlin - 在 Kotlin 中获取参数化类型的参数
- c# - 尝试使用递归方法 c# 反转数组时的错误输出