OpenLayers 地图上的线条符号化

Symbolization of lines on the OpenLayers map

如何对线进行复杂的符号化?

我不知道这种风格叫什么,但你需要这样的东西:

  1. broken line?

  2. dotted line (helped here):

    [
        new ol.style.Style({
            stroke: new ol.style.Stroke({
                width: 5,
                color: 'black'
            })
        }),
        new ol.style.Style({
            stroke: new ol.style.Stroke({
                width: 3,
                color: 'white',
                lineCap: 'butt',
                lineDash: [9, 9]
            })
        })
    ]
    

我在任何地方都找不到有关如何设置这种样式的信息,尽管它们经常在示意图上找到。

第 2 步可以使用样式函数来完成,该函数在样式中设置锯齿线几何形状。此代码基于 ,但不是显示平行线,而是沿着原始线交替绘制每条平行线上的最近点。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.6.1/css/ol.css" />
    <style>
      html, body, .map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
      }
    </style>
</head>
<body>

<div id="map" class="map"></div>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.6.1/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/9.4.4/math.min.js"></script>
<script>

function styleFunction(width, strokeWidth, color) {
  var style = new ol.style.Style({
    stroke: new ol.style.Stroke({
      color: color,
      width: strokeWidth
    })
  });
  return function(feature, resolution) {
    var lines = [];
    var geom = feature.getGeometry();
    if (geom.getType() == "LineString") {
      for (var line = 0; line < 2; line++) {
        var dist = width * resolution * (line - 1/2);
        var coords = [];
        var counter = 0;
        geom.forEachSegment(function(from, to) {
          var angle = Math.atan2(to[1] - from[1], to[0] - from[0]);
          var newFrom = [
            Math.sin(angle) * dist + from[0],
            -Math.cos(angle) * dist + from[1]
          ];
          var newTo = [
            Math.sin(angle) * dist + to[0],
            -Math.cos(angle) * dist + to[1]
          ];
          coords.push(newFrom);
          coords.push(newTo);
          if (coords.length > 2) {
            var intersection = math.intersect(coords[counter], coords[counter+1], coords[counter+2], coords[counter+3]);
            coords[counter+1] = (intersection) ? intersection : coords[counter+1];
            coords[counter+2] = (intersection) ? intersection : coords[counter+2];
            counter += 2;
          }
        });
        lines.push(new ol.geom.LineString(coords));
      }
      var length = geom.getLength();
      var intervals = Math.ceil(length / (width * resolution));
      var coords = [];
      coords.push(geom.getCoordinateAt(0));
      for (var i= 0; i < intervals; i++) {
        coords.push(
          lines[i % 2].getClosestPoint(
            geom.getCoordinateAt((2 * i + 1) / (intervals * 2))
          )
        );
      }
      coords.push(geom.getCoordinateAt(1));
      style.setGeometry(new ol.geom.LineString(coords));
      return style;
    }
  };
}


var raster = new ol.layer.Tile({
  source:  new ol.source.OSM() 
});

var source = new ol.source.Vector();

var vector = new ol.layer.Vector({
  source: source,
  style: styleFunction(4, 2, 'black')
});

var map = new ol.Map({
  layers: [raster, vector],
  target: 'map',
  view: new ol.View({
    center: [-11000000, 4600000],
    zoom: 4
  })
});

map.addInteraction(new ol.interaction.Draw({
  source: source,
  type: 'LineString',
  style: styleFunction(4, 2, 'red')
}));

</script>

</body>
</html>