OpenLayers v5を使用して、いくつかの描画ツールをマップに追加しているところです。そのようなタスクで、ドキュメントや箱から出してすぐに使用できないカスタム図面が必要になると、同心円になります。
どこから始めればいいのかわからないので、2つの質問があります。
どういうわけか、単一のジオメトリを作成して、例に示されているgeometryFunction
ように使用できますか、それとも、円ごとに1つずつ、複数のフィーチャを作成する必要がありますか?
そしてGeometry
、OpenLayersと連携するためにスタンドアロンとして作成する場合、正確には何が必要ですか?X、Y座標のコレクション?
ドキュメントの描画例を使用して、これを自分で理解しようとして、オブジェクトから座標を取得し、その後それを再作成して、以下のように手動でソースに追加しようとしました。
const feature = new Feature({
geometry: new Circle(
[
/**
* These are the nubmers that come out of a native Circle drawing
* when console.log'ing the feature.getGeomety.getFlatCoordinates().
* No idea if this is how I'd get or set those values.
*/
[-10448062.740758311, 4941309.912009362],
[ -9953141.960354999, 4941309.912009362],
]
)
});
source.addFeature(feature);
これはエラーではありませんが、円を表示できません。
インタラクションタイプがCircleの場合、座標には円の中心と現在の点の2つのペア[x、y]が含まれます。半径と回転を計算するには、これで十分です。ジオメトリは単一の単純なジオメトリである必要があるため、同心円をマルチポリゴンに変換する必要があります。
// OpenLayers default drawing style doesn't include stroke for MultiPolygon
var white = [255, 255, 255, 1];
var blue = [0, 153, 255, 1];
var width = 3;
styles = [
new ol.style.Style({
fill: new ol.style.Fill({
color: [255, 255, 255, 0.5]
})
}),
new ol.style.Style({
stroke: new ol.style.Stroke({
color: white,
width: width + 2
})
}),
new ol.style.Style({
stroke: new ol.style.Stroke({
color: blue,
width: width
})
}),
new ol.style.Style({
image: new ol.style.Circle({
radius: width * 2,
fill: new ol.style.Fill({
color: blue
}),
stroke: new ol.style.Stroke({
color: white,
width: width / 2
})
}),
zIndex: Infinity
})
];
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var source = new ol.source.Vector({wrapX: false});
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 typeSelect = document.getElementById('type');
var draw; // global so we can remove it later
function addInteraction() {
var value = typeSelect.value;
if (value !== 'None') {
var geometryFunction;
if (value === 'Square') {
value = 'Circle';
geometryFunction = ol.interaction.Draw.createRegularPolygon(4);
} else if (value === 'Box') {
value = 'Circle';
geometryFunction = ol.interaction.Draw.createBox();
} else if (value === 'Star') {
value = 'Circle';
geometryFunction = function(coordinates, geometry) {
var center = coordinates[0];
var last = coordinates[1];
var dx = center[0] - last[0];
var dy = center[1] - last[1];
var radius = Math.sqrt(dx * dx + dy * dy);
var rotation = Math.atan2(dy, dx);
var newCoordinates = [];
var numPoints = 12;
for (var i = 0; i < numPoints; ++i) {
var angle = rotation + i * 2 * Math.PI / numPoints;
var fraction = i % 2 === 0 ? 1 : 0.5;
var offsetX = radius * fraction * Math.cos(angle);
var offsetY = radius * fraction * Math.sin(angle);
newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
}
newCoordinates.push(newCoordinates[0].slice());
if (!geometry) {
geometry = new ol.geom.Polygon([newCoordinates]);
} else {
geometry.setCoordinates([newCoordinates]);
}
return geometry;
};
} else if (value === 'Concentric') {
value = 'Circle';
geometryFunction = function(coordinates, geometry) {
var center = coordinates[0];
var last = coordinates[1];
var dx = center[0] - last[0];
var dy = center[1] - last[1];
var radius = Math.sqrt(dx * dx + dy * dy);
var rotation = Math.atan2(dy, dx);
var newCoordinates = [];
var numCircles = 3;
for (var i = numCircles; i > 0; --i) {
var circle = new ol.geom.Circle(center, radius * i/numCircles);
newCoordinates.push(ol.geom.Polygon.fromCircle(circle, 64, rotation).getCoordinates());
}
if (!geometry) {
geometry = new ol.geom.MultiPolygon(newCoordinates);
} else {
geometry.setCoordinates(newCoordinates);
}
return geometry;
};
}
draw = new ol.interaction.Draw({
source: source,
type: value,
geometryFunction: geometryFunction,
style: styles
});
draw.on('drawend', function(evt){
if (evt.feature.getGeometry().getType() == 'MultiPolygon') {
var polygons = evt.feature.getGeometry().getPolygons();
for (var i = 0; i < polygons.length; ++i) {
center = ol.extent.getCenter(polygons[i].getExtent());
radius = ol.extent.getWidth(polygons[i].getExtent())/2;
if (i == 0) {
evt.feature.setGeometry(new ol.geom.Circle(center, radius));
} else {
source.addFeature(new ol.Feature(new ol.geom.Circle(center, radius)));
}
}
}
});
var modify = new ol.interaction.Modify({source: source});
map.addInteraction(modify);
map.addInteraction(draw);
}
}
/**
* Handle change event.
*/
typeSelect.onchange = function() {
map.removeInteraction(draw);
addInteraction();
};
addInteraction();
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.map {
width: 100%;
height: 80%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>
<form class="form-inline">
<label>Shape type </label>
<select id="type">
<option value="Circle">Circle</option>
<option value="Square">Square</option>
<option value="Box">Box</option>
<option value="Star">Star</option>
<option value="Concentric">Concentric</option>
<option value="None">None</option>
</select>
</form>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加