繁体   English   中英

Openlayers日期线交叉线串消失

[英]Openlayers dateline crossing linestring disappears

我正在使用openlayers,当我尝试在地图上添加多次跨越日期线的线串时出现问题。

为了显示连续段中两个世界的线串,我添加了一个HandleDateline()函数,该函数返回修改后的坐标(向左或向右移动)

但是,当您在左侧环境中放大到当前的固定视图时,线串将消失。 同样,如果您尝试将地图向左移动,该线也会消失。

奇怪的是,如果线相交超过1次,则左侧世界上的线串消失,否则右侧世界上的情况相同。 太注意了,从我将要张贴的datelinecrossing[]删除前3个点或最后3个点。

我希望连续的线串跨越国际日期变更线而不会出现任何消​​失的问题。

如果有更好的方法,我愿意接受所有想法。 这是bin: ol dateline problem

您必须以编程方式在日期线上分割与日期线交叉的线。

 var points = [ [-170, -10], [170, 0], [-170, 10] ]; var vectorSource = new ol.source.Vector(); vectorSource.addFeature(createFeature(points)); var vectorLayer = new ol.layer.Vector({ source: vectorSource, style: new ol.style.Style({ stroke: new ol.style.Stroke({ width: 2, color: "red" }) }) }); var osmLayer = new ol.layer.Tile({ source: new ol.source.OSM() }); var map = new ol.Map({ layers: [osmLayer, vectorLayer], target: document.getElementById("map"), view: new ol.View({ center: ol.proj.transform([180, 0], "EPSG:4326", "EPSG:3857"), zoom: 3 }) }); var graticule = new ol.Graticule({ strokeStyle: new ol.style.Stroke({ color: "rgba(255,120,0,0.9)", width: 1.5, lineDash: [0.5, 4] }), showLabels: true }); graticule.setMap(map); // ------------------------------------------------- function createFeature(points) { var pointsSplitted = []; var pointsArray = []; pointsSplitted.push(points[0]); var lastLambda = points[0][0]; for (var i = 1; i < points.length; i++) { var lastPoint = points[i - 1]; var nextPoint = points[i]; if (Math.abs(nextPoint[0] - lastLambda) > 180) { var deltaX = xToValueRange(nextPoint[0] - lastPoint[0]); var deltaY = nextPoint[1] - lastPoint[1]; var deltaXS = xToValueRange(180 - nextPoint[0]); var deltaYS; if (deltaX === 0) { deltaYS = 0; } else { deltaYS = deltaY / deltaX * deltaXS; } var sign = lastPoint[0] < 0 ? -1 : 1; pointsSplitted.push([180 * sign, nextPoint[1] + deltaYS]); pointsArray.push(pointsSplitted); pointsSplitted = []; pointsSplitted.push([-180 * sign, nextPoint[1] + deltaYS]); } pointsSplitted.push(nextPoint); lastLambda = nextPoint[0]; } pointsArray.push(pointsSplitted); var geom = new ol.geom.MultiLineString(pointsArray); geom.transform("EPSG:4326", "EPSG:3857"); var feature = new ol.Feature({ geometry: geom }); return feature; } function xToValueRange(x) { if (Math.abs(x) > 180) { var sign = x < 0 ? -1 : 1; return x - 2 * 180 * sign; } else { return x; } } 
 html, body, #map { width: 100%; height: 100%; overflow: hidden } 
 <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> <body> <div id="map" class="map" tabindex="0"></div> </body> 

简化HandleDateline以便所有坐标都位于正常世界的西部或左侧世界的东部,似乎可以解决此问题(因此,如果几何图形越过日期线,则范围将从左侧世界开始)

 function HandleDateline(array) {
        for (var i = 0; i < array.length ; i++) {
            if (array[i][0] > 0) {
                array[i][0] -= 360;
            }
        }
    }

但是,在右侧的世界中,日期线以西的点似乎呈现在线串的下方,而日期线以东的点则位于线串的上方。 移动HandleDateline(datelinecrossing); 上述datelinecrossing.forEach解决此问题。

您可能还需要考虑对点使用多点几何体(除非您需要它们可以单独选择)。

HandleDateline(datelinecrossing);
var pdlcrossing = new ol.Feature({
    geometry: new ol.geom.MultiPoint(datelinecrossing).transform('EPSG:4326', 'EPSG:3857')
});
drawingSource.addFeature(pdlcrossing);
var dlcrossing = new ol.Feature({
    geometry: new ol.geom.LineString(datelinecrossing).transform('EPSG:4326', 'EPSG:3857')
});
drawingSource.addFeature(dlcrossing);

在右边的世界中,在日期线以西缩放时仍然存在问题,因此我认为每种几何都需要两组,一组向左偏移,另一组向右360度:

function PlotGeometries(datelinecrossing){
  var pgeom = new ol.geom.MultiPoint(datelinecrossing);
  var pdlcrossing = new ol.Feature({
    geometry: pgeom.clone().transform('EPSG:4326', 'EPSG:3857')
  });
  drawingSource.addFeature(pdlcrossing);
  pgeom.translate(360,0);
  var pdlcrossing2 = new ol.Feature({
    geometry: pgeom.transform('EPSG:4326', 'EPSG:3857')
  });
  drawingSource.addFeature(pdlcrossing2);
  var geom = new ol.geom.LineString(datelinecrossing);
  var dlcrossing = new ol.Feature({
    geometry: geom.clone().transform('EPSG:4326', 'EPSG:3857')
  });
  drawingSource.addFeature(dlcrossing);
  geom.translate(360,0);
  var dlcrossing2 = new ol.Feature({
    geometry: geom.transform('EPSG:4326', 'EPSG:3857')
  });
  drawingSource.addFeature(dlcrossing2);
}

只需为您正在处理的世界的一部分设置地图视图的范围即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM