I'm trying to change few options of Google Maps drawing manager by clicking a button using Angular. But I receive error messages saying that DrawingManager variable is undefined.
I initialized Google Maps and DrawingManager in ngAfterViewInit function in an Angular Component. Google Map object and the Drawing Manager object are assigned to variables in the component as shown in the code. I want to change the few options of Drawing Manager by Clicking a button in the component. "drawControlEnable" function is called by clicking the button. But DrawingManager object is undefined inside the "drawControlEnable" function. I have put the Google Maps Script in the index.html and the code for the component.
Index.html
<script async defer src="https://maps.googleapis.com/maps/api/js?key=XXXXX&libraries=drawing,geometry"></script>
Angular Component
import {Component, OnInit, ViewChild, AfterViewInit} from '#angular/core';
import { } from '#types/googlemaps';
.....
.....
#ViewChild('gmap') gmapElement: any;
map: google.maps.Map;
shapes = [];
coordinatesArray = [];
drawingManager: any;
ngAfterViewInit() {
var mapProp = {
center: new google.maps.LatLng(7.515073, 80.723066),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map(this.gmapElement.nativeElement, mapProp);
this.drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: null,
drawingControl: false,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['polygon']
},
markerOptions: {icon: 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png'},
polygonOptions: {
editable: true,
draggable: true
}
});
this.drawingManager.setMap(this.map);
}
.....
.....
drawControlEnable() {
this.drawingManager.setDrawingMode(google.maps.drawing.OverlayType.MARKER);
this.drawingManager.setOptions({drawingControl : true});
}
How I can change DrawingManager options by clicking a button?
This is how i create a map and change the drawing control option with a button:
First I declare two variables: one for the map and one for the drawingManager
theMap: any;
drawingManager: any;
the I create the map in ngOnInit and call the drawingManager:
this.theMap = this.initMap(lat, lng);
if(this.theMap) {
this.initDrawingManager(this.theMap)
}
the two functions for creating the map and initializing the drawing manager are:
initMap(lat, lng) {
let mapProp = {
center: new google.maps.LatLng(lat, lng),
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
let map = new google.maps.Map(document.getElementById("map"), mapProp);
let marker = new google.maps.Marker({
icon: 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',
animation: google.maps.Animation.DROP,
position: { lat: lat, lng: lng },
map: map
})
return map;
}
and
initDrawingManager(map) {
this.drawingManager = new google.maps.drawing.DrawingManager({
// drawingMode: google.maps.drawing.OverlayType.MARKER,
drawingControl: false,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['circle', 'polygon']
},
// markerOptions: {icon: 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png'},
polygonOptions: {
draggable: true,
editable: true
},
circleOptions: {
// fillColor: '#ffff00',
// fillOpacity: 1,
// strokeWeight: 5,
draggable: true,
clickable: true,
editable: true,
zIndex: 1
}
});
this.drawingManager.setMap(map);
}
The function that changes the drawingControl option is:
change() {
this.drawingManager.setOptions({
drawingControl: true
});
}
and the HTML is:
<button
(click)="change()">
change
</button>
By clicking the button, the drawing controls will appear on the map.
Our difference is that I create the map in ngOnInit.
Related
I make polygon drawing on my map.
Here is function for drawingManager
drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
drawingControlOptions: {
drawingModes: [
google.maps.drawing.OverlayType.RECTANGLE,
google.maps.drawing.OverlayType.POLYGON
]
},
polygonOptions: {
fillColor: 'green',
fillOpacity: 0.4,
strokeWeight: 1,
clickable: true,
zIndex: 1,
editable: false
}
});
I need to calculate bounds for polygon. I read, that I cannot do it via .getBounds like with square.
So I found here answer
I tried one of answers.
So now my code looks like this.
drawingManager.addListener('polygoncomplete', function (polygon) {
var bounds = new google.maps.LatLngBounds();
polygon.forEach(function (feature) {
if (feature.getGeometry().getType() === 'Polygon') {
feature.getGeometry().forEachLatLng(function (latlng) {
bounds.extend(latlng);
});
}
});
console.dir(bounds);
});
and in console I get this error.
Index.js:1673 Uncaught TypeError: polygon.forEach is not a function
at this row polygon.forEach(function (feature) {
Where is problem and how I can solve it?
See the documentation:
A polygon has a .getPaths() method, which returns a MVCArray of LatLng objects.
drawingManager.addListener('polygoncomplete', function(polygon) {
var bounds = new google.maps.LatLngBounds();
polygon.getPaths().forEach(function(path) {
path.forEach(function(latlng) {
bounds.extend(latlng);
map.fitBounds(bounds);
});
});
});
proof of concept fiddle
code snippet:
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var drawingManager = new google.maps.drawing.DrawingManager({
map: map,
drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
drawingControlOptions: {
drawingModes: [
google.maps.drawing.OverlayType.RECTANGLE,
google.maps.drawing.OverlayType.POLYGON
]
},
polygonOptions: {
fillColor: 'green',
fillOpacity: 0.4,
strokeWeight: 1,
clickable: true,
zIndex: 1,
editable: false
}
});
drawingManager.addListener('polygoncomplete', function(polygon) {
var bounds = new google.maps.LatLngBounds();
polygon.getPaths().forEach(function(path) {
path.forEach(function(latlng) {
bounds.extend(latlng);
map.fitBounds(bounds);
});
});
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,drawing&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>
While it's not documented here:
https://developers.google.com/maps/documentation/javascript/reference/polygon
The Google Maps API for Polygons does have a getBounds() method.
The API documentation should be updated to include:
getBounds()
Parameters: None
Return Value: LatLngBounds
Returns the bounds of the Polygon.
\\ define map up here, draw polygons
let bounds = polygon.getBounds();
let rect = new google.maps.Rectangle({
bounds: bounds,
map: thisMap
});
I'am using the google maps Drawing Layer (Library) to draw shapes on my map.
Once finished drawing all the shapes I call "toGeoJson" function from the google maps api.
The object i receive look like this:
object received when calling "toGeoJSON"
I can't figure out what I'am doing wrong.
I am just trying to create a GeoJson out of the shapes drawn on the map.
I am not pasting any code because the drawing part is all done by the drawing library and the "toGeoJson" function is done by the google maps API.
There is no toGeoJSON method on the drawing manager, that only exists on the Data class
Drawing objects on the map with the drawing manager doesn't add them to the DataLayer.
You can add the objects from the drawing manager to the Data Layer, then call toGeoJson on that.
To prevent adding duplicate objects to the map, use a separate Data object, rather than the one on the map.
proof of concept fiddle
(some code from the related question: Export geoJSON data from Google Maps)
code snippet:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -34.397,
lng: 150.644
},
zoom: 8
});
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.MARKER,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.MARKER,
google.maps.drawing.OverlayType.CIRCLE,
google.maps.drawing.OverlayType.POLYGON,
google.maps.drawing.OverlayType.POLYLINE,
google.maps.drawing.OverlayType.RECTANGLE
]
},
markerOptions: {
icon: 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png'
},
circleOptions: {
fillColor: '#ffff00',
fillOpacity: 1,
strokeWeight: 5,
clickable: false,
editable: true,
zIndex: 1
}
});
drawingManager.setMap(map);
var dataLayer = new google.maps.Data();
// from https://stackoverflow.com/questions/25072069/export-geojson-data-from-google-maps
// from http://jsfiddle.net/doktormolle/5F88D/
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
switch (event.type) {
case google.maps.drawing.OverlayType.MARKER:
dataLayer.add(new google.maps.Data.Feature({
geometry: new google.maps.Data.Point(event.overlay.getPosition())
}));
break;
case google.maps.drawing.OverlayType.RECTANGLE:
var b = event.overlay.getBounds(),
p = [b.getSouthWest(), {
lat: b.getSouthWest().lat(),
lng: b.getNorthEast().lng()
},
b.getNorthEast(), {
lng: b.getSouthWest().lng(),
lat: b.getNorthEast().lat()
}
]
dataLayer.add(new google.maps.Data.Feature({
geometry: new google.maps.Data.Polygon([p])
}));
break;
case google.maps.drawing.OverlayType.POLYGON:
dataLayer.add(new google.maps.Data.Feature({
geometry: new google.maps.Data.Polygon([event.overlay.getPath().getArray()])
}));
break;
case google.maps.drawing.OverlayType.POLYLINE:
dataLayer.add(new google.maps.Data.Feature({
geometry: new google.maps.Data.LineString(event.overlay.getPath().getArray())
}));
break;
case google.maps.drawing.OverlayType.CIRCLE:
dataLayer.add(new google.maps.Data.Feature({
properties: {
radius: event.overlay.getRadius()
},
geometry: new google.maps.Data.Point(event.overlay.getCenter())
}));
break;
}
});
google.maps.event.addDomListener(document.getElementById('save'), 'click', function() {
dataLayer.toGeoJson(function(obj) {
document.getElementById('geojson').innerHTML = JSON.stringify(obj);
});
})
}
google.maps.event.addDomListener(window, 'load', initMap);
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=drawing&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<input id="save" value="save" type="button" />
<div id="geojson"></div>
<div id="map"></div>
I already create a polygon and draggable marker, but my problem is if the marker is inside in the polygon, it will alert "NO", it should be "YES"? My code is here:
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=drawing,geometry"></script>
<script type="text/javascript">
function initialize() {
var coor = [];
var mapOptions = {
center: new google.maps.LatLng(7.0704771, 125.608522),
zoom: 17,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
var dragable_marker = new google.maps.Marker({
position : new google.maps.LatLng(7.0704771, 125.608522),
map : map,
draggable : true,
title: "Your customer location"
});
drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.NONE,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
//google.maps.drawing.OverlayType.MARKER,
google.maps.drawing.OverlayType.POLYGON
]
},
markerOptions: {
icon: 'img/pin.png'
},
polygonOptions: {
fillColor: '#66d9ef',
fillOpacity: 0.5,
strokeColor: '#1A8BD6',
strokeWeight: 2,
clickable: true,
editable: false,
draggable: false,
zIndex: 1
}
});
drawingManager.setMap(map);
var created_poly = new google.maps.Polygon({path:coor,
map: map,
strokeColor:"#0000FF",
strokeOpacity:0.8,
strokeWeight:2,
fillColor:"#0000FF",
fillOpacity:0.4
});
google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
drawingManager.setDrawingMode(null);
var arr=[];
polygon.getPath().forEach(
function(latLng){
arr.push(latLng.toString());
}
)
coor = arr.join(',\n');
drawingManager.setOptions({
drawingControl: false,
});
});
google.maps.event.addListener(dragable_marker,"dragend", function() {
if(google.maps.geometry.poly.containsLocation(dragable_marker.getPosition(), created_poly) == true) {
alert("yes"); // if marker is inside in polygon
} else {
alert("no"); // if marker is outside in polygon
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<style type="text/css">
#map-canvas{
height: 300px;
}
</style>
<body>
<div id="map-canvas"></div>
</body
What is my error?
One algorithm to solve this is point in polygon. See an explanation http://en.wikipedia.org/wiki/Point_in_polygon
And you can find code implementing this for the Google Maps JS API V3 here:https://github.com/tparkin/Google-Maps-Point-in-Polygon
I'm using this exmaple from https://developers.google.com/maps/documentation/javascript/examples/drawing-tools to enable user to choose a point and enable user to draw a circle around it.
However, I need also to:
get the lat/lang of center of circle that user draw.
get the radius of circle.
also the code allows user to draw more than one circle, if possible, I need to restrict user to draw only one circle, if user draw another circle, first circle should be removed.
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.MARKER,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.MARKER,
google.maps.drawing.OverlayType.CIRCLE,
google.maps.drawing.OverlayType.POLYGON,
google.maps.drawing.OverlayType.POLYLINE,
google.maps.drawing.OverlayType.RECTANGLE
]
},
markerOptions: {
icon: 'images/beachflag.png'
},
circleOptions: {
fillColor: '#ffff00',
fillOpacity: 1,
strokeWeight: 5,
clickable: false,
editable: true,
zIndex: 1
}
});
drawingManager.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
See http://jsfiddle.net/stevejansen/2HpA6
(function () {
var circle;
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.MARKER,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.CIRCLE]
},
circleOptions: {
fillColor: '#ffff00',
fillOpacity: 1,
strokeWeight: 5,
clickable: false,
editable: true,
zIndex: 1
}
});
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'circlecomplete', onCircleComplete);
}
function onCircleComplete(shape) {
if (shape == null || (!(shape instanceof google.maps.Circle))) return;
if (circle != null) {
circle.setMap(null);
circle = null;
}
circle = shape;
console.log('radius', circle.getRadius());
console.log('lat', circle.getCenter().lat());
console.log('lng', circle.getCenter().lng());
}
google.maps.event.addDomListener(window, 'load', initialize);
})();
GoogleMap map;
// Add a circle in Sydney
Circle circle = map.addCircle(new CircleOptions()
.center(new LatLng(-33.87365, 151.20689))
.radius(10000)
.strokeColor(Color.RED)
.fillColor(Color.BLUE));
<-- to get radius of any location in map, use this code. It shows the radius value from center of map to x and y coordinates.-->
Toast.makeText(app.getBaseContext(),***[circle.getRadius()][1]***,
Toast.LENGTH_SHORT).show();
I have following Demo where I try to draw Polygon by using Google maps v3.
But when I try to draw Polygon its invisible till I change map center.
Do I need repaint it somehow?
Here is the code:
var map2;
function linesmap(){
var myOptions = {
zoom: 14,
center: new google.maps.LatLng(51.425, -0.955),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// map2 = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var options = {
zoom: 14,
center: new google.maps.LatLng(51.425, -0.955),
mapTypeId: google.maps.MapTypeId.ROADMAP,
panControl: false,
scrollwheel: true,
draggable: true,
rotateControl: false,
mapTypeControl: true,
scaleControl: true,
streetViewControl: true,
zoomControl: true,
disableDoubleClickZoom: false
};
map2 = new google.maps.Map(document.getElementById("map_canvas"), options);
buildDrawManager();
}
var buildDrawManager = function(){
console.log('buildDrawManager');
// Creates a drawing manager attached to the map that allows the user to draw
// markers, lines, and shapes.
drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: null,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.POLYGON
]
},
polygonOptions: {
fillColor: '#1E90FF',
strokeWeight: 0,
fillOpacity: 0.3,
editable: true
},
map: map2
});
google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) { });
}
[EDIT]
It happens on Chrome version 32.0.1700.76
#fessy Your fix doesn't seem to be working for me. I was able to get it working by touching the zoom level. You don't event notice it happen.
document.getElementById("map_canvas").onclick = function(){
if(drawingManager.getDrawingMode() !== google.maps.drawing.OverlayType.HAND){
map2.setZoom(map2.getZoom() + 1);
map2.setZoom(map2.getZoom() - 1);
}
};
http://plnkr.co/edit/TP8TIjvdRHHOyg6NKQWc?p=preview
Thanks to #geocodezip that posted workaround to solve this issue.
Here is a fix:
Changed version
https://maps.googleapis.com/maps/api/js?sensor=false&v=3&libraries=geometry,visualization,drawing
to exp.:
https://maps.googleapis.com/maps/api/js?sensor=false&v=3.exp&libraries=geometry,visualization,drawing
and Plunker with fix