[英]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>
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.