簡體   English   中英

使用開放層自動繪制路徑的第一個頂點

[英]Draw automatically the first vertice of a path with Open Layers

我想幫助用戶使用OpenLayers輸入片段的方向。

我有一個表格,用戶可以輸入一個點的方位角,但是我想通過以下方式為他提供幫助:

  • 當用戶單擊按鈕時,開始在地圖上繪制線段的第一個頂點(該第一個頂點是已知點)
  • 那么用戶只需單擊第二個頂點即可自動計算方位。

請參見此處的小提琴或下面的SO代碼段。

我快完成了:繪制線段時可以計算方位。 但是腳本的結尾處有一個例外:我無法讓OL自動繪制段的第一點。

謝謝任何可以幫助的人。

 <script src="http://openlayers.org/api/OpenLayers.js"></script> <body> <div id="map" style="height: 500px"></div> </body> <script> var CONSTANTS = { MAP_FROM_PROJECTION: new OpenLayers.Projection("EPSG:4326"), // Transform from WGS 1984 MAP_TO_PROJECTION: new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator Projection }; function radians(n) { return n * (Math.PI / 180); } function degrees(n) { return n * (180 / Math.PI); } function computeBearing(startLat, startLong, endLat, endLong) { startLat = radians(startLat); startLong = radians(startLong); endLat = radians(endLat); endLong = radians(endLong); var dLong = endLong - startLong; var dPhi = Math.log(Math.tan(endLat / 2.0 + Math.PI / 4.0) / Math.tan(startLat / 2.0 + Math.PI / 4.0)); if (Math.abs(dLong) > Math.PI) { if (dLong > 0.0) dLong = -(2.0 * Math.PI - dLong); else dLong = (2.0 * Math.PI + dLong); } return (degrees(Math.atan2(dLong, dPhi)) + 360.0) % 360.0; } map = new OpenLayers.Map("map"); map.addLayer(new OpenLayers.Layer.OSM()); map.setCenter(new OpenLayers.LonLat(3, 47).transform(CONSTANTS.MAP_FROM_PROJECTION, CONSTANTS.MAP_TO_PROJECTION), 6); var lineLayer = new OpenLayers.Layer.Vector("Line Layer"); map.addLayers([lineLayer]); var lineControl = new OpenLayers.Control.DrawFeature(lineLayer, OpenLayers.Handler.Path, { handlerOptions: { maxVertices: 2, freehandMode: function(evt) { return false; } }, featureAdded: function(feature) { var drawnLinePoints = feature.geometry.getVertices(); var lonlat1 = drawnLinePoints[0].transform(CONSTANTS.MAP_TO_PROJECTION, CONSTANTS.MAP_FROM_PROJECTION); var lonlat2 = drawnLinePoints[1].transform(CONSTANTS.MAP_TO_PROJECTION, CONSTANTS.MAP_FROM_PROJECTION); var bearingValue = computeBearing(lonlat1.y, lonlat1.x, lonlat2.y, lonlat2.x); console.log(bearingValue); } }); map.addControl(lineControl); lineControl.activate(); var handler; for (var i = 0; i < map.controls.length; i++) { var control = map.controls[i]; if (control.displayClass === "olControlDrawFeature") { handler = control.handler; break; } } // Here I have an exception in the console : I would like // OL to draw hat point automatically. handler.addPoint(new OpenLayers.Pixel(50, 50)); </script> 

OpenLayers.Handler.Path.addPointOpenLayers.Pixel ,而不在OpenLayers.LonLat

/**
 * Method: addPoint
 * Add point to geometry.  Send the point index to override
 * the behavior of LinearRing that disregards adding duplicate points.
 *
 * Parameters:
 * pixel - {<OpenLayers.Pixel>} The pixel location for the new point.
 */
addPoint: function(pixel) {
    this.layer.removeFeatures([this.point]);
    var lonlat = this.layer.getLonLatFromViewPortPx(pixel); 
    this.point = new OpenLayers.Feature.Vector(
        new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat)
    );
    this.line.geometry.addComponent(
        this.point.geometry, this.line.geometry.components.length
    );
    this.layer.addFeatures([this.point]);
    this.callback("point", [this.point.geometry, this.getGeometry()]);
    this.callback("modify", [this.point.geometry, this.getSketch()]);
    this.drawFeature();
    delete this.redoStack;
}

除了添加addPointByLonLat方法之外,我實際上沒有其他實現此目的的好方法:

OpenLayers.Handler.Path.prototype.addPointByLonLat = function(lonLat) {
    this.layer.removeFeatures([this.point]);
    this.point = new OpenLayers.Feature.Vector(
        new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat)
    );
    this.line.geometry.addComponent(
        this.point.geometry, this.line.geometry.components.length
    );
    this.layer.addFeatures([this.point]);
    this.callback("point", [this.point.geometry, this.getGeometry()]);
    this.callback("modify", [this.point.geometry, this.getSketch()]);
    this.drawFeature();
    delete this.redoStack;
};

或子類作為您自己的處理程序類(可能更干凈)。

筆記:

  • addPoint不是API方法(因此addPointByLonLat也不是)。 這可能會導致版本更改出現問題。
  • 不要在開發中使用壓縮/縮小的JS,並檢查所用方法的文檔。
  • 下次考慮在https://gis.stackexchange.com/提問
  • 考慮要求對JS進行代碼審查。

您也可以使用insertXY(x,y)函數來插入具有地理坐標的點http://dev.openlayers.org/docs/files/OpenLayers/Handler/Path-js.html#OpenLayers.Handler.Path。 insertXY

    lonlat = new OpenLayers.LonLat(1,45);
    lonlat.transform(CONSTANTS.MAP_FROM_PROJECTION,CONSTANTS.MAP_TO_PROJECTION);
    handler.createFeature(new OpenLayers.Pixel(100, 100));
    handler.insertXY(lonlat.lon,lonlat.lat);
    handler.drawFeature();

您可以在此處使用原始jsfiddle的分支進行檢查: http : //jsfiddle.net/mefnpbn2/

有關解決方案, 請參見此小提琴

tldr:

// draw the first point as I needed, as if a user has clicked on the map
handler.modifyFeature(new OpenLayers.Pixel(50, 50), true); 

// draw a first point on the map (not clicked). 
// This will be the initial point where the "cursor" is on the map, as long as 
// the user hasn't hovered onto the map with its mouse. This make the blue 
// line showing current segment to appear, without this segment is drawn but 
// no feedback is given to the user as long as he hasn't clicked.
handler.addPoint(new OpenLayers.Pixel(50, 50)); // 

暫無
暫無

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

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