Thomasの回答から始めて、GeoJSONから追加さDrawingManager
れたsだけでなく、で作成されたオーバーレイの編集を可能にする実装を次に示します。Feature
私にとっての主な苦労は、によって作成された同様の名前のタイプと一緒にgoogle.maps
作成された-prefixedオーバーレイタイプを使用することでした。最終的には、組み込みオブジェクトを無視して、すべてを再作成されたオーバーレイとして保存し、編集イベントリスナーを設定して、描画時に個別に呼び出しました。最初に描画されたオーバーレイとロードされたフィーチャは破棄されます。DrawingManager
google.maps.Data
Feature
addFromGeoJson()
Data
setMap()
プロセスは次のようになります。
- マップを初期化します。
addfeature
機能が追加されるたびに検出するイベントリスナーを追加します。これはaddGeoJson()
、それぞれFeature
の間に発生し、対応するオーバーレイタイプとジオメトリを取得し、それらをユーティリティ関数に渡してaddFeature()
オーバーレイを作成します。
- GeoJSONをロードします。これにより、ロードされたすべてのオブジェクトに対して上記のイベントリスナーが起動されます。
- を初期化し
DrawingManager
ます。
- オーバーレイのタイプ( 、、、および)
{overlay}complete
ごとにイベントリスナーを追加します。発生すると、これらのイベントは最初にオーバーレイが有効かどうかを判断し(たとえば、ポリゴンに3つ以上の頂点がある)、次に呼び出して、オーバーレイのタイプとジオメトリを渡します。polygon
polyline
marker
addFeature()
呼び出されると、addFeature()
オーバーレイが再作成され、該当するすべてのイベントリスナーが設定されます。最後に、オーバーレイが配列に保存され、マップに表示されます。
// GeoJSON containing previously stored data (optional)
var imported = {
type: "FeatureCollection",
features: [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-73.985603, 40.748429
],
},
properties: {
activity: "Entry",
}
}, ]
};
// this will fill with map data as you import it from geojson or draw
var features = {
polygons: [],
lines: [],
markers: []
};
// set default drawing styles
var styles = {
polygon: {
fillColor: '#00ff80',
fillOpacity: 0.3,
strokeColor: '#008840',
strokeWeight: 1,
clickable: true,
editable: true,
zIndex: 1
},
polyline: {
strokeColor: '#ffff00',
strokeWeight: 3,
clickable: true,
editable: true,
zIndex: 2
},
marker: {
clickable: true,
draggable: true,
zIndex: 3
}
}
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 40.748429,
lng: -73.985603
},
zoom: 18,
noClear: true,
mapTypeId: 'satellite',
navigationControl: true,
mapTypeControl: false,
streetViewControl: false,
tilt: 0
});
// add this listener BEFORE loading from GeoJSON
map.data.addListener('addfeature', featureAdded);
// load map features from geojson
map.data.addGeoJson(imported);
// initialize drawing tools
var drawingManager = new google.maps.drawing.DrawingManager({
// uncomment below line to set default drawing mode
// drawingMode: 'marker',
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['polygon', 'polyline', 'marker']
},
polygonOptions: styles.polygon,
polylineOptions: styles.polyline,
markerOptions: styles.marker
});
drawingManager.setMap(map);
// for each drawing mode, set a listener for end of drawing
drawingManager.addListener('polygoncomplete', function(polygon) {
// delete drawing if doesn't have enough points
if (polygon.getPath().getLength() < 3) {
alert('Polygons must have 3 or more points.');
polygon.getPath().clear();
}
// otherwise create new feature and delete drawing
else {
addFeature('Polygon', polygon.getPath());
polygon.setMap(null);
}
});
drawingManager.addListener('polylinecomplete', function(line) {
// delete drawing if doesn't have enough points
if (line.getPath().getLength() < 2) {
alert('Lines must have 2 or more points.');
line.getPath().clear();
}
// otherwise create new feature and delete drawing
else {
addFeature('Polyline', line.getPath());
line.setMap(null);
}
});
drawingManager.addListener('markercomplete', function(marker) {
// point geometries have only one point by definition,
// so create new feature and delete drawing
addFeature('Point', marker.getPosition());
marker.setMap(null);
updateGeoJSON();
});
}
// this function gets called when GeoJSON gets loaded
function featureAdded(e) {
switch (e.feature.getGeometry().getType()) {
case 'Polygon':
addFeature('Polygon', e.feature.getGeometry().getAt(0).getArray());
break;
case 'LineString':
addFeature('Polyline', e.feature.getGeometry().getArray());
break;
case 'Point':
addFeature('Point', e.feature.getGeometry().get());
}
map.data.remove(e.feature);
}
function addFeature(type, path) {
switch (type) {
case 'Polygon':
var polygon = new google.maps.Polygon(styles.polygon);
polygon.setPath(path);
// listeners for detecting geometry changes
polygon.getPath().addListener('insert_at', someFunction)
polygon.getPath().addListener('set_at', someFunction);
polygon.getPath().addListener('remove_at', someFunction);
polygon.getPath().addListener('dragend', someFunction);
// delete vertex using right click
polygon.addListener('rightclick', function(e) {
if (e.vertex == undefined) return;
if (polygon.getPath().getLength() == 3) {
polygon.setMap(null);
features.polygons = features.polygons.filter(isValid);
} else {
polygon.getPath().removeAt(e.vertex);
outputAsGeoJSON();
}
});
// add it to our list of features
features.polygons.push(polygon);
// and display it on the map
polygon.setMap(map);
break;
case 'Polyline':
var line = new google.maps.Polyline(styles.polyline);
line.setPath(path);
line.getPath().addListener('insert_at', someOtherFunction);
line.getPath().addListener('set_at', someOtherFunction);
line.getPath().addListener('remove_at', someOtherFunction);
line.getPath().addListener('dragend', someOtherFunction);
// allow right-click vertex deletion
line.addListener('rightclick', function(e) {
if (e.vertex == undefined) return;
if (line.getPath().getLength() == 2) {
line.setMap(null);
features.lines = features.lines.filter(isValid);
} else {
line.getPath().removeAt(e.vertex);
outputAsGeoJSON();
}
});
// add it to our list of features
features.lines.push(line);
// and display it on the map
line.setMap(map);
break;
case 'Point':
var marker = new google.maps.Marker(styles.marker);
marker.setPosition(path);
// make a splashy entrance
marker.setAnimation(google.maps.Animation.DROP);
// detect modifications
marker.addListener('drag', function(e) {
// unnecessary bouncing just to throw you off
marker.setAnimation(google.maps.Animation.BOUNCE);
});
marker.addListener('dragend', function(e) {
// make the bouncing stop
marker.setAnimation(null);
})
// allow right-click deletion
marker.addListener('rightclick', function(e) {
marker.setMap(null);
features.markers = features.markers.filter(isValid);
outputAsGeoJSON();
});
// add it to our list of features
features.markers.push(marker);
// and display it on the map
marker.setMap(map);
break;
}
outputAsGeoJSON();
}
function someFunction() {
// do stuff
}
function someOtherFunction() {
// do other stuff
}
// utility function for reuse any time someone right clicks
function isValid(f) {
return f.getMap() != null;
}
function outputAsGeoJSON() {
// we're only using the Data type here because it can export as GeoJSON
var data = new google.maps.Data;
// add all the polygons in our list of features
features.polygons.forEach(function(polygon, i) {
data.add({
geometry: new google.maps.Data.Polygon([polygon.getPath().getArray()]),
properties: {
description: 'I am a polygon'
}
});
});
// and add all the lines
features.lines.forEach(function(line, i) {
data.add({
geometry: new google.maps.Data.LineString(line.getPath().getArray()),
properties: {
description: 'I am a line'
}
});
});
// and finally any markers
features.markers.forEach(function(marker, i) {
data.add({
geometry: new google.maps.Data.Point(marker.getPosition()),
properties: {
description: 'I am a marker'
}
});
});
// GeoJSONify it
data.toGeoJson(function(json) {
document.getElementById('geojson').value = JSON.stringify(json);
});
}
https://jsfiddle.net/pqdu05s9/1/