簡體   English   中英

在 OpenLayers 中繪制帶末端的多線串

[英]Draw multilinestring with ends in OpenLayers

我需要能夠在 OpenLayers 5 中繪制多線串(這很容易),並帶有可自定義的線端。

例如,如果我正在創建一個標尺工具,我希望多線串的末端是一個“T”,以准確顯示線條的開始和結束位置。 線條末端的“記號”必須是線條幾何形狀的一部分。

我已經這樣構建了我的生產線......

  const draw: olDraw = new olDraw({
  source: MapValues.drawSource,
  type: 'LineString',
  style: new olStyle({
    fill: new olFill({
      color: 'rgba(255, 255, 255, 0.2)'
    }),
    stroke: new olStroke({
      color: '#ffcc33',
      width: 2
    }),
    image: new CircleStyle({
      radius: 7,
      fill: new olFill({
        color: '#ffcc33'
      })
    })
  })
})
draw.on('drawstart', (e: olDrawEvent) => {
  const tool = this;
  let dStartMeasureTT = this.measureTooltip;
  // set sketch
  this.sketch = e.feature;
  var tooltipCoord = e.coordinate;
  tool.listener = this.sketch.getGeometry().on('change', function (evt) {
    var geom = evt.target;
    var output;
    output = tool.formatLength(geom);
    tooltipCoord = geom.getLastCoordinate();
    tool.measureTooltipElement.innerHTML = output;
    tool.measureTooltip.setPosition(tooltipCoord);
  });
});
draw.on('drawend', (e: olDrawEvent) => {
  const format: olGeoJson = new olGeoJson();
  this.shapeString = format.writeGeometry(e.feature.getGeometry(),
    { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857', rightHanded: false });
  this.featureGeometry = transform(e.feature.getGeometry().getCoordinates(), 'EPSG:3857', 'EPSG:4326');
  // Pull up Create object modal
  const initialState = {
    message: '',
    title: 'Ruler Label',
    iconSize: 'xx-large',
    iconType: 'error',
    fontSize: 'x-large',
    inCharLimit: 50,
    inObjName: this.measureTooltipElement.innerHTML
  };
  this.bsModalRef = this.modalService.show(CreateobjectComponent, Object.assign({ class: 'modal-sm 
  modal-dialog-centered', initialState }, this.config));
  this.bsModalRef.content.closeBtnName = 'OK';
  this.bsModalRef.content.modalProcess.subscribe((objName) => {
    if (objName) {
      this.saveRulerToDb(objName);
      this.createMeasureTooltip();
    }
  });
});
map.addInteraction(draw);
}
}

您可以在 drawend 事件中將繪制的 LineString 幾何圖形轉換為 MultiLineString,然后將 append 開始和結束線轉換為它。

 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, }); var map = new ol.Map({ layers: [raster, vector], target: 'map', view: new ol.View({ center: [-11000000, 4600000], zoom: 4, }), }); var draw = new ol.interaction.Draw({ source: source, type: 'LineString', }); draw.on('drawend', function(e) { var lineString = e.feature.getGeometry(); var multiLineString = new ol.geom.MultiLineString([]); multiLineString.appendLineString(lineString); var size = lineString.getLength() / 20; // or use a fixed size if you prefer var coords = lineString.getCoordinates(); // start var dx = coords[1][0] - coords[0][0]; var dy = coords[1][1] - coords[0][1]; var rotation = Math.atan2(dy, dx); var startLine = new ol.geom.LineString([ [coords[0][0], coords[0][1] - size], [coords[0][0], coords[0][1] + size] ]); startLine.rotate(rotation, coords[0]); // end var lastIndex = coords.length - 1; var dx = coords[lastIndex - 1][0] - coords[lastIndex][0]; var dy = coords[lastIndex - 1][1] - coords[lastIndex][1]; var rotation = Math.atan2(dy, dx); var endLine = new ol.geom.LineString([ [coords[lastIndex][0], coords[lastIndex][1] - size], [coords[lastIndex][0], coords[lastIndex][1] + size] ]); endLine.rotate(rotation, coords[lastIndex]); multiLineString.appendLineString(startLine); multiLineString.appendLineString(endLine); e.feature.setGeometry(multiLineString); }); map.addInteraction(draw);
 /* Always set the map height explicitly to define the size of the div * element that contains the map. */.map { width: 100%; height: 100%; } /* Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
 <:DOCTYPE html> <html lang="en"> <head> <.-- from How to set different colors for a lineString OpenLayers 5 https://stackoverflow.com/questions/66351764/how-to-set-different-colors-for-a-linestring-openlayers-5 https,//codesandbox:io/s/gpx-forked-6wpdy --> <meta charset="UTF-8"> <title>LineString T-ends</title> <.-- Pointer events polyfill for old browsers: see https.//caniuse:com/#feat=pointer --> <script src="https.//unpkg.com/elm-pep"></script> </head> <body> <script src="https.//cdn.polyfill?io/v2/polyfill,min.js.features=requestAnimationFrame,Element:prototype.classList.URL"></script> <script src="https.//cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6:5.0/build/ol.js"></script> <link rel="stylesheet" href="https.//openlayers.org/en/v6.5.0/css/ol.css" type="text/css"> <div id="map" class="map"></div> </body> </html>

  1. 制作一個圖標,該圖標是行尾的橫線:
橫桿圖標
“橫桿”圖標
  1. 將其添加到 LineStrings 的末尾:
var styleFunction = function (feature) {
  var geometry = feature.getGeometry();
  var styles = [
    // linestring
    new ol.style.Style({
      stroke: new ol.style.Stroke({
        color: 'blue', // '#ffcc33',
        width: 2,
      }),
    }) ];
    var coords = geometry.getCoordinates();
    // start
    var dx = coords[1][0] - coords[0][0];
    var dy = coords[1][1] - coords[0][1];
    var rotation = Math.atan2(dy, dx);
    // start crossbar
    styles.push(
      new ol.style.Style({
        geometry: new ol.geom.Point(coords[0]),
        image: new ol.style.Icon({
          // url encoded svg icon to prevent cross-domain issues
          src: "data:image/svg+xml;utf8,%3Csvg width='30' height='40' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 10 10 h 1 v 20 h -1 Z' fill='black' stroke='black'/%3E%3C/svg%3E",
          anchor: [10, 0.5],
          anchorXUnits: 'pixels',
          rotateWithView: true,
          rotation: -rotation,
        }),
      })
    );
    // end
    var lastIndex = coords.length-1;
    var dx = coords[lastIndex-1][0] - coords[lastIndex][0];
    var dy = coords[lastIndex-1][1] - coords[lastIndex][1];
    var rotation = Math.atan2(dy, dx);
    // end crossbar
    styles.push(
      new ol.style.Style({
        geometry: new ol.geom.Point(coords[lastIndex]),
        image: new ol.style.Icon({
          // url encoded svg icon to prevent cross-domain issues
          src: "data:image/svg+xml;utf8,%3Csvg width='30' height='40' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 10 10 h 1 v 20 h -1 Z' fill='black' stroke='black'/%3E%3C/svg%3E",
          anchor: [9.5, 0.5],
          anchorXUnits: 'pixels',
          rotateWithView: true,
          rotation: -rotation,
        }),
      })
    );
  return styles;
};

活生生的例子

地圖截圖

代碼片段:

 var raster = new ol.layer.Tile({ // TileLayer({ source: new ol.source.OSM(), }); var source = new ol.source.Vector(); // VectorSource(); var styleFunction = function(feature) { var geometry = feature.getGeometry(); var styles = [ // linestring new ol.style.Style({ stroke: new ol.style.Stroke({ color: 'blue', // '#ffcc33', width: 2, }), }) ]; var coords = geometry.getCoordinates(); // start var dx = coords[1][0] - coords[0][0]; var dy = coords[1][1] - coords[0][1]; var rotation = Math.atan2(dy, dx); // start crossbar styles.push( new ol.style.Style({ geometry: new ol.geom.Point(coords[0]), image: new ol.style.Icon({ // url encoded svg icon to prevent cross-domain issues src: "data:image/svg+xml;utf8,%3Csvg width='30' height='40' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 10 10 h 1 v 20 h -1 Z' fill='black' stroke='black'/%3E%3C/svg%3E", anchor: [10, 0.5], // center vertically at end of line anchorXUnits: 'pixels', rotateWithView: true, rotation: -rotation, }), }) ); // end var lastIndex = coords.length - 1; var dx = coords[lastIndex - 1][0] - coords[lastIndex][0]; var dy = coords[lastIndex - 1][1] - coords[lastIndex][1]; var rotation = Math.atan2(dy, dx); // end crossbar styles.push( new ol.style.Style({ geometry: new ol.geom.Point(coords[lastIndex]), image: new ol.style.Icon({ // url encoded svg icon to prevent cross-domain issues src: "data:image/svg+xml;utf8,%3Csvg width='30' height='40' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 10 10 h 1 v 20 h -1 Z' fill='black' stroke='black'/%3E%3C/svg%3E", anchor: [9.5, 0.5], anchorXUnits: 'pixels', rotateWithView: true, rotation: -rotation, }), }) ); return styles; }; var lineString = new ol.geom.LineString([ [-13015491.561823528, 5172360.467799401], [-12379535.48649086, 5182144.407419903] ]) // create the feature var feature = new ol.Feature({ geometry: lineString, name: 'Line' }); source.addFeature(feature); var vector = new ol.layer.Vector({ // VectorLayer({ source: source, style: styleFunction, }); 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', }) );
 /* Always set the map height explicitly to define the size of the div * element that contains the map. */.map { width: 100%; height: 100%; } /* Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
 <:DOCTYPE html> <html lang="en"> <head> <.-- from How to set different colors for a lineString OpenLayers 5 https://stackoverflow.com/questions/66351764/how-to-set-different-colors-for-a-linestring-openlayers-5 https,//codesandbox:io/s/gpx-forked-6wpdy --> <meta charset="UTF-8"> <title>LineString T-ends</title> <.-- Pointer events polyfill for old browsers: see https.//caniuse:com/#feat=pointer --> <script src="https.//unpkg.com/elm-pep"></script> </head> <body> <script src="https.//cdn.polyfill?io/v2/polyfill,min.js.features=requestAnimationFrame,Element:prototype.classList.URL"></script> <script src="https.//cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6:5.0/build/ol.js"></script> <link rel="stylesheet" href="https.//openlayers.org/en/v6:5.0/css/ol.css" type="text/css"> <div id="map" class="map"></div> <script src="http.//www;google-analytics;com/urchin.js" type="text/javascript"> </script> <script type="text/javascript"> _uacct = "UA-162157-1"; urchinTracker(); </script> </body> </html>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM