我需要用OpenLayers实现一个测量工具,我想在段上显示距离,智能管理规模(每10米一段标记,然后每50米,100米,1公里,5公里,例如...),非常像GoogleMaps"测量距离"工具。
有没有图书馆这样做?实施它的好方法是什么?
答案 0 :(得分:0)
简而言之:不,我不知道任何提供您想要的开箱即用的库或类。
选项1:自定义ScaleLine
ScaleLine(参见api docs)可以选择提供自己的渲染功能(参见code)。默认实现只计算距离并通过调用内部函数 @Override
public void onTabTransaction(Fragment currentFragment, int i) {
appBarLayout.setFitsSystemWindows(currentFragment instanceof SecondFragment);
}
将其显示为{number} {scale}
,然后更新ScaleLine的innerHtml。
理论上你可以替换该方法并自己设置innerHTML。这种方法可能会限制您使用库的开发变体,因为生产代码已缩小,并且这些元素(updateElement_
,innerElement_
)未标记为api。
element_
选项2:使用具有自定义LineString样式的绘图功能
因此可能过于复杂,我建议您使用new ol.control.ScaleLine({
render: function(mapEvent) {
// do stuff
}
});
功能。 Measure Example向我们展示了在用户绘制线条时如何绘制内容。您可以将它与自定义样式组合在一个LineString上。
ol.interaction.Draw
// TODO split the uses drawn line into segments, like this mockup
const line = new ol.geom.LineString([
[20.0, 50.0],
[30.0, 47.0],
[40.0, 47.0],
[50.0, 47.0]
]);
line.transform('EPSG:4326', 'EPSG:3857');
const lineFeature = new ol.Feature(line);
const lineSource = new ol.source.Vector({
features: [lineFeature]
});
function segmentText(coord, coord2) {
const coord_t = ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326');
let coordText = coord_t[1].toFixed(0) + '/' + coord_t[0].toFixed(0);
if(coord2) {
const length = ol.Sphere.getLength(new ol.geom.LineString([coord2, coord]));
const distance = (Math.round(length / 1000 * 100) / 100) + ' km';
coordText = coordText + '\n' + distance;
} else {
coordText = coordText + '\n0';
}
return new ol.style.Text({
text: coordText,
fill: new ol.style.Fill({
color: "#00f"
}),
offsetY: 25,
align: 'center',
scale: 1,
});
}
function styleFunction(feature) {
var geometry = feature.getGeometry();
var styles = [
// linestring style
new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#ff0000',
width: 2
})
})
];
function createSegmentStyle(coord, coord2, rotation) {
return new ol.style.Style({
geometry: new ol.geom.Point(coord),
image: new ol.style.Icon({
src: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAIAAADdv/LVAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAUSURBVBhXY1Da6MPEwMDAxMDAAAALMAEkQYjH8gAAAABJRU5ErkJggg==',
anchor: [0.75, 0.5],
rotateWithView: true,
rotation: -rotation,
scale: 4
}),
text: segmentText(coord, coord2)
})
};
const firstCoord = geometry.getFirstCoordinate();
geometry.forEachSegment(function (start, end) {
var dx = end[0] - start[0];
var dy = end[1] - start[1];
var rotation = Math.atan2(dy, dx);
if (firstCoord[0] === start[0] && firstCoord[1] === start[1]) {
styles.push(createSegmentStyle(start, null, rotation));
}
styles.push(createSegmentStyle(end, firstCoord, rotation));
});
return styles;
}
const map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.Stamen({ layer:'toner-lite' })
}),
new ol.layer.Vector({
source: lineSource,
style: styleFunction
})
],
view: new ol.View({
center: ol.proj.transform(
[35, 45], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});