I am trying to use google maps to allow a user to create multiple editabled/draggable polygons. Everything works fine from a desktop browser, but on a mobile/touch device all polygons are no longer draggable once a user adds a new polygon to the map. Polygons loaded on the map during initialize are draggable as expected.
I know touch events are not really supported by the google maps api, but is there a workaround I can do?
Simplified example:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: {lat: 24.886, lng: -70.268},
mapTypeId: 'terrain'
});
var triangleCoords = [
{lat: 25.774, lng: -80.190},
{lat: 18.466, lng: -66.118},
{lat: 32.321, lng: -64.757},
{lat: 25.774, lng: -80.190}
];
// Construct the polygon.
var bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
draggable: true
});
bermudaTriangle.setMap(map);
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.MARKER,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['polygon']
},
polygonOptions: {
fillColor: '#ffff00',
fillOpacity: 1,
strokeWeight: 5,
draggable: true,
zIndex: 10000
}
});
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
drawingManager.setOptions({
drawingMode: null
});
});
}
google.maps.event.addDomListener(window, 'load', initMap);
https://codepen.io/cyberjus/pen/XEVoer
Upon load from a mobile device, the first polygon is draggable, but once another polygon is drawn, neither can be dragged anymore. I am testing on an actual iPad, so I dont know if it is IOS specific or not.
Related
Looking to create multiple routes from Location a to location B using Polylines on Google map.
I am having issue in giving colours to two polylines stacked over each other.
Basic use is to show progress in route traversed from A to B with the one already covered in orange and the left route in grey colour.
I am able to give colour to only one Polyline. The other polyline superimposed is not seen even when opacity of the top polyline is reduced.
See JSfiddle- https://jsfiddle.net/8yx3vLo6/3/
I am able to give colour to only one Polyline. The other polyline superimposed/stacked is not seen even when opacity of the top polyline is reduced.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: {lat: 0, lng: -180},
mapTypeId: 'terrain'
});
var flightPlanCoordinates = [
{lat: 37.772, lng: -122.220},
{lat: 21.291, lng: -160.821},
{lat: -18.142, lng: 178.431},
{lat: -27.467, lng: 153.027}
];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: 'red',
strokeOpacity: 1.0,
strokeWeight: 1
});
flightPath.setMap(map);
var map1 = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: {lat: 0, lng: -180},
mapTypeId: 'terrain'
});
var flightPlanCoordinates1 = [
{lat: 17.772, lng: -35.220},
{lat: 21.291, lng: -160.821},
{lat: -18.142, lng: 178.431},
{lat: -27.467, lng: 153.027}
];
var flightPath1 = new google.maps.Polyline({
path: flightPlanCoordinates1,
geodesic: true,
strokeColor: '#000',
strokeOpacity: 1,
strokeWeight: 1
});
flightPath1.setMap(map1);
}
You currently have 2 maps (map and map1). One polyline is on map the other on map1. First thing you need to do is put each polyline on the same map.
To make it so you can see both, put one on top of the other, with the one on top having a smaller stroke.
var flightPlanCoordinates = [
{lat: 37.772, lng: -122.220},
{lat: 21.291, lng: -160.821},
{lat: -18.142, lng: 178.431},
{lat: -27.467, lng: 153.027}
];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: 'yellow',
strokeOpacity: 1.0,
strokeWeight: 6 // first polyline added is on bottom, make stroke bigger
});
flightPath.setMap(map);
var flightPlanCoordinates1 = [
{lat: 37.772, lng: -122.220},
{lat: 21.291, lng: -160.821},
{lat: -18.142, lng: 178.431},
{lat: -27.467, lng: 153.027}
];
var flightPath1 = new google.maps.Polyline({
path: flightPlanCoordinates1,
geodesic: true,
strokeColor: 'blue',
strokeOpacity: 1.0,
strokeWeight: 2 // second polyline added is on top, make stroke smaller
});
flightPath1.setMap(map);
proof of concept fiddle
code snippet:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: {
lat: 0,
lng: -180
},
mapTypeId: 'terrain'
});
var flightPlanCoordinates = [
{lat: 37.772, lng: -122.220},
{lat: 21.291, lng: -160.821},
{lat: -18.142, lng: 178.431},
{lat: -27.467, lng: 153.027}
];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: 'yellow',
strokeOpacity: 1.0,
strokeWeight: 6 // first polyline added is on bottom, make stroke bigger
});
flightPath.setMap(map);
var flightPlanCoordinates1 = [
{lat: 37.772, lng: -122.220},
{lat: 21.291, lng: -160.821},
{lat: -18.142, lng: 178.431},
{lat: -27.467, lng: 153.027}
];
var flightPath1 = new google.maps.Polyline({
path: flightPlanCoordinates1,
geodesic: true,
strokeColor: 'blue',
strokeOpacity: 1.0,
strokeWeight: 2 // second polyline added is on top, make stroke smaller
});
flightPath1.setMap(map);
var bounds = new google.maps.LatLngBounds();
bounds.extend(flightPlanCoordinates1[0]);
bounds.extend(flightPlanCoordinates1[3]);
map.fitBounds(bounds);
}
html,
body,
#map {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
So i'm currently playing around with turfjs. And i'm trying to add a squaregrid inside a polygon.
So here's the code
var triangleCoords = [
{ lat: 25.774, lng: -80.19 },
{ lat: 18.466, lng: -66.118 },
{ lat: 32.321, lng: -64.757 },
{ lat: 25.774, lng: -80.19 }
];
// Construct the polygon.
var bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
const geoJSON = {
type: 'Polygon',
coordinates: []
};
// convert to bermudaTriangle path to geojson
for (let point of bermudaTriangle.getPath().getArray()) {
geoJSON.coordinates.push([point.lat(), point.lng()]);
}
const feature = turf.feature(geoJSON);
const bbox = turf.bbox(feature);
// ERROR: this one's showing Infinity values
console.table(bbox);
const grid = turf.squareGrid(bbox, 50, {
units: "miles",
mask: feature
});
map.data.addGeoJson(grid);
and looking at the console, it shows Infinity values for bbox as commented on the code.
I've added a link for the code
https://codepen.io/chan-dev/pen/yrdRoM
geoJSON is not a valid GeoJSON object for Polygon in the provided example, that's the reason why turf.bbox returns invalid result. GeoJSON for polygon could be constructed via turf.polygon like this:
var triangleCoords = [
{ lat: 25.774, lng: -80.19 },
{ lat: 18.466, lng: -66.118 },
{ lat: 32.321, lng: -64.757 },
{ lat: 25.774, lng: -80.19 }
];
var data = triangleCoords.map(coord => {
return [coord.lng, coord.lat];
});
var geojson = turf.polygon([data]);
and bounding box calculated like this:
const bbox = turf.bbox(geojson);
Modified CodePen
Below is a standard code taken from Google Map api V3 documentation. If you chnage the polygon options to editable and draggable, when you hover/click on the vertices of the polygon, you get the following error:
Uncaught TypeError: Cannot read property '__e3_' of null
The error is inconsistent in that it appears on an ad-hoc basis.
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.POLYGON,
drawingControl: false,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
},
markerOptions: { icon: 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png' },
polygonOptions: {
fillColor: '#ffff00',
fillOpacity: 1,
strokeWeight: 5,
clickable: true,
editable: true,
draggable:true,
zIndex: 1
}
});
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'overlaycomplete', function (event) {
drawingManager.setDrawingMode(null);
});
}
initMap();
Is this a bug in the api ?
Would appreciate any input on this matter.
Many thanks.
I am able to draw the lines on the maps using the following code:
var flightPlanCoordinates1 = [
{ lat: 22.53412218657744, lng: -95.4580076783896 },
{ lat: 25.265810430433756, lng: -96.51269517838955 },
{ lat: 24.308304859959954, lng: -92.4916990846396 },
{ lat: 28.150714091845007, lng: -94.07373033463955 },
{ lat: 26.530793950651773, lng: -89.92089830338955 },
{ lat: 25.5635039073037, lng: -87.63574205338955 },
{ lat: 26.491469591982202, lng: -85.30664049088955 },
{ lat: 28.65323578152034, lng: -86.80078111588955 },
{ lat: 28.845876611067364, lng: -88.91015611588955 },
{ lat: 27.587415049297192, lng: -88.33886705338955 },
{ lat: 25.84068541364038, lng: -94.00781236588955 }
];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates1,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(map);
But in a real application as we are getting data from db and populating it , I am not able to get the lines on the map
So, here is the object declaration and initialization:
flightPlanCoordinates = [];
for (var i = 0; i < jsonOut.length; i++) {
jsonCor["lat"] = jsonOut[i]["lat"];
jsonCor["long"] = jsonOut[i]["long"];
flightPlanCoordinates.push(jsonCor);
}
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(map);
The data in the object is as below:
0: Object
lat: 23.222417047162825
long: -95.45800767838955
__proto__: Object
1:Object
so on which is exactly in the example shown above.
What is the problem with the object which is constructed?
You probably need to do this:
for (var i = 0; i < jsonOut.length; i++) {
flightPlanCoordinates.push({
lat: parseFloat(jsonOut[i]["lat"]),
lng: parseFloat(jsonOut[i]["long"]
});
}
Firstly make the structure of your coordinates match what you were doing originally, i.e. {lat: x, lng: y} instead of {lat, x, long: y}.
Secondly because you're reading it from JSON, you probably also need to do parseFloat() on the values, otherwise they're likely to be strings.
I am using the sample from google map API to draw the circle and wanted to place the population value inside the circle for the plots can we do this in google map API
Example:https://developers.google.com/maps/documentation/javascript/examples/circle-simple
inside the ping circle as shown in the demo ,want to place the value of the population
One option is to use the InfoBox third party library to label the circles.
Proof of concept fiddle
code snippet:
// This example creates circles on the map, representing populations in North
// America.
function initMap() {
// Create the map.
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: {
lat: 37.090,
lng: -95.712
},
mapTypeId: google.maps.MapTypeId.TERRAIN
});
// Construct the circle for each value in citymap.
// Note: We scale the area of the circle based on the population.
for (var city in citymap) {
// Add the circle for this city to the map.
var cityCircle = new google.maps.Circle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
zIndex: -100,
center: citymap[city].center,
radius: Math.sqrt(citymap[city].population) * 100
});
var myOptions = {
content: "population<br>" + citymap[city].population,
boxStyle: {
background: '#FFFFFF',
color: '#000000',
textAlign: "center",
fontSize: "8pt",
width: "50px"
},
disableAutoPan: true,
pixelOffset: new google.maps.Size(-25, -10), // left upper corner of the label
position: new google.maps.LatLng(citymap[city].center.lat,
citymap[city].center.lng),
closeBoxURL: "",
isHidden: false,
pane: "floatPane",
zIndex: 100,
enableEventPropagation: true
};
var ib = new InfoBox(myOptions);
ib.open(map);
}
}
google.maps.event.addDomListener(window, "load", initMap);
// First, create an object containing LatLng and population for each city.
var citymap = {
chicago: {
center: {
lat: 41.878,
lng: -87.629
},
population: 2714856
},
newyork: {
center: {
lat: 40.714,
lng: -74.005
},
population: 8405837
},
losangeles: {
center: {
lat: 34.052,
lng: -118.243
},
population: 3857799
},
vancouver: {
center: {
lat: 49.25,
lng: -123.1
},
population: 603502
}
};
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/infobox/src/infobox.js"></script>
<div id="map"></div>