使用“开放层”自动绘制路径的第一条垂直线
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.addPoint
适用于OpenLayers.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/
有关解决方案,请参阅此fiddle。
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)); //
相关文章:
- 使用onclick绘制SVG路径
- Html5-使用SVG路径绘制的组织层次结构在左手边被剪裁
- 使用javascript中的for循环在画布上绘制路径
- 绘制动画openlayers线条字符串路径
- 在html画布中绘制更平滑的路径
- 我无法使用 gmaps.js 绘制路径
- 如何在拉斐尔中删除我可能想要在两秒钟后重新绘制的路径
- 绘制 SVG 拉斐尔路径会出错并且不接受变量
- Javascript:如何确定SVG路径绘制方向
- JavaScript - 有没有办法在内容下绘制SVG路径
- 如何更改拉斐尔 JS 绘制的路径宽度和高度
- 从 GPS 捕捉到道路的 GEO 位置绘制路径
- 谷歌地图API - 在数组中使用Lat Lng坐标绘制折线飞行路径
- Javascript HTML5 Canvas 绘制路径问题
- 在HTML5中绘制路径,然后绘制图像
- 填充路径取决于绘制顺序
- 使用 jQuery SVG 绘制外部 svg 路径
- SVG路径绘制和擦除动画
- 路径绘制与d3
- SVG路径绘制和图像填充