Get Lat Lng when drawing a polygon with Google Maps drawing tool - javascript

I got the Google Map and Drawing Tools displayed on the map. I can draw the shapes (circle, polygon, rectangle ...) on the map. For the start I am using the example code from Google Maps JavaScript get started page: https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/drawing-tools
I was able to find a lot of examples on have to draw/make a shape object by providing all the properties and LatLng.
How do I get a LatLng for the shape that I just draw by using one of the drawing tools form Drawing Tools toolbar?
I am planing to make an application which will allow user to draw shapes on the map and save the LatLng in to database (i will be using MySql), so later the shape can be displayed again on the map as per request.
Please help.

There are a few ways to get the coordinates of the shapes you draw on the map. Specifically for polygons you can add an event listener to the map like so. The easiest way is to add an event listener to the map for when a polygon is finished drawing.
google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
const coords = polygon.getPath().getArray().map(coord => {
return {
lat: coord.lat(),
lng: coord.lng()
}
});
console.log(JSON.stringify(coords, null, 1));
// SAVE COORDINATES HERE
});
Each type of drawing has a different format for saving so for something like circles you'd do
google.maps.event.addListener(drawingManager, 'circlecomplete', function(circle) {
const radius = circle.getRadius();
// Save circle here
});
You also have the option of adding an event to listen for all of the events by listening to the overlaycomplete event but in that case you'd have to handle the different types inside the event.
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
if (event.type == 'circle') {
// Handle Circle using event.overlay
}
if (event.type == 'polygon') {
// Handle Polygon using event.overlay
}
});
Here's an example:
https://jsfiddle.net/juop8q3n/1/
And here's my sources:
https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/drawinglayer#drawing_events
https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/reference#drawing-on-the-map
EDIT
Another way I've seen people save the data is by adding an event listener to the map to get the GeoJSON data, which is a standard format for saving drawing data.
Link: http://jsfiddle.net/y89rbfLo/

Related

Here Maps: Currently visible markers

I have a HERE maps based javascript map on a website with a list of markers.
When the user zooms and pans the map, the mapviewchangeend event is triggered.
In that event, how can I find out which markers are currently visible?
The H.Maps object has a getObjectsWithin method, but that one needs a polygon - which I don't know how to obtain.
As polygon you should use the bounds from ViewModel's getLookAtData method:
map.addEventListener('mapviewchangeend', (e) => {
let bounds = map.getViewModel().getLookAtData().bounds;
map.getObjectsWithin(bounds, (objects) => {
console.log(objects);
})
})
For more information check the H.map.ViewModel.getObjectsWithin documentation.

Drawing boundaries on a map with LeafletJS

I'm starting to play with code that can generate maps. I am now looking at OSM (OpenStreetMaps) as a great solution. Also LeafletJS makes it very easy to draw maps based on OSM. So far so good.
I would like to be able to draw an outline (boundary) of a county and am trying to understand how this process will look like. Do I first make a call to find coords and then pass them into Leaflet or is there a better way?
I can get boundaries using Nominatim API, but calling like this:
https://nominatim.openstreetmap.org/ui/search.html?state=tx&county=Lee
And I can draw area in Leaflet like this:
var polygon = L.polygon([
[51.509, -0.08],
[51.503, -0.06],
[51.51, -0.047]
]).addTo(mymap);
So, am I overthinking or this is how it works?
You can create a single function to get the county geometry and add it to map. Try the following code:
function drawCountyBoundary(county, state)
{
url = `https://nominatim.openstreetmap.org/search.php?county=${county}&state=${state}&polygon_geojson=1&format=jsonv2`
fetch(url).then(function(response) {
return response.json();
})
.then(function(json) {
geojsonFeature = json[0].geojson;
L.geoJSON(geojsonFeature).addTo(map);
});
}
drawCountyBoundary('Lee', 'Tx')

How to get modified and original geojson points after editing polygon in leaflet?

I have a geojson feature I've created. After editing, I know there is a draw:edited event. How do I get the original points that the polygon consisted of, and is it possible to get the new polygon points? How? Is it possible to know which vertices were changed or added?
I tried the following, all of which does not work:
map.on('draw:edited', function (e) {
var type = e.layerType;
var layer = e.layer; // this is giving undefined errors
var shape = layer.toGeoJSON() // this is undefined
var shape_for_db = JSON.stringify(shape);
});
The draw:created event fired on L.Map returns a L.LayerGroup as e.layers, which contains all the features that just have been edited. This is because you can edit multiple features at once before pressing the save button. You can iterate the L.LayerGroup and then fetch the GeoJSON:
map.on('draw:edited', function (e) {
e.layers.eachLayer(function (layer) {
console.log(layer.toGeoJSON());
});
});

Plot Centroid of Feature Layer Polygon

Here is the rest service I'm working from:
http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3
My current call for displaying the feature layer is as follows:
var recLayer = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3",{
infoTemplate: recParkTemplate,
outFields: ["STATE_NAME"]
});
map.addLayer(recLayer);
However, instead of plotting the polygon on the map as this is an esriGeometricPolygon. I would rather have it plot on the map like a esriGeometryPoint. I know this method in getting the specific polygon's centroid:
https://developers.arcgis.com/javascript/jsapi/polygon-amd.html#getcentroid
My problem is I can't figure out how to cycle among all polygons in the feature layer and then plot those polygons. I can only point and click and display similar to how this ESRI sample works: https://developers.arcgis.com/javascript/jssamples/util_label_point.html
Thank you for your assistance.
Here is the current site if you would like to take a look at it: http://joshferrell.net/ece_project/
to cycle among all geometries in your feature layer you can do something like this:
recLayer.on("update-end", function changeHandler(evt) {
require(["dojo/_base/array"], function (array) {
array.forEach(recLayer.graphics, function (entry, i) {
console.debug(entry, "at index", i);
});
});
});
inside the loop use the getCentroid and add the result to the map

Capture Google Maps Polyline On Click (Per Start/End)

Description
I am currently working with Google Maps V3 for our client and they've asked us to implement a drawing tool that will allow them to create connected stream of lines and calculate the distance. However, it seems the Google Maps V3 Drawing Manager library is very limited in how it allows us to capture the click events for a polyline.
Our Code
google.maps.event.addListener(map, 'click', function(event){
//TODO: Store lat/long of click for distance calculation later
});
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
//TODO: Display the total distance of the line
});
The Goal
google.maps.event.addListener(drawingManager, 'polylineclick', function(event){
//TODO: Store lat/long of line for distance calculation and display updated distance.
});
As you can see, we want to capture the lat/long as the user is creating the polyline and display the distance as each line is created, not once the entire polyline is completed.
Also, I know we can imitate this by creating custom handlers and doing some magic with the map's click method and drawing lines manually between lat/longs, but it seems weird that the Google Maps API wouldn't have a click method for their Drawing Manager.
Clarification
The end goal is to have functionality so while drawing a polyline, we can display the total length of the polyline dynamically. I.E. I begin by drawing a line, a section appears that says "Total Line is X", I click a second spot to create a second line and the text updates to "x" + "y", I click a third and it updates to "x" + "y" + "z", etc. This is why we were hoping there is an event to handle "lineDrawn" or "polylineClick" to store these lat/longs to we can calculate the length for dynamically created lines without having the user stop drawing lines to see the total length.
Edit: Updated addListener in Our Goal to use drawingManager, not map.
Edit: Addition of Clarification section.
Basically you want to chain the two together like this:
var thePolyLine = new google.maps.Polyline({
polyLineOptions
}).setMap(map).addListener("click", function(event){
//click event
});
============= EDIT =============
Ok, I clearly didn't read the OP's question entirely.
Looks like the markercomplete event returns a marker. I'd create a global Array of marker objects, then you can run a distance check between each on catching that event.
var markers = new Array();
google.maps.event.addListener(theDrawingManager, "markercomplete", function (marker) {
markers.push(marker);
});
Then, you can loop through them, and computeDistanceBetween any or all points.
============= EDIT #2 =============
My Fiddle of the solution! (I updated the code with more comments and fixed an error, made it obvious that distance is in meters):
http://jsfiddle.net/8Xqaw/12/
Right-click the map to add points to measure.
Distance is in meters, btw. It will update distance when you drag points, too. And there is a click function for the polyLine itself.
Clicking the first point again will allow you to connect the final point with the first point to create a polygon, then you can click and drag to move the polygon around (which moves the points as well)...
Try this :3
var PolylineOption = {
strokeColor : "blue",
strokeOpacity : 0.5,
strokeWeight : 5
};
var Display;
var rendererOptions = {
draggable : true,
suppressMarkers : true,
polylineOptions : PolylineOption
};
var Service = new google.maps.DirectionsService();
Display = new google.maps.DirectionsRenderer(this.rendererOptions);
Display.setMap(map);
Service.route(this.request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
Display.setDirections(response);
}
});
google.maps.event.addListener(PolylineOption, 'click', function() {
alert(this.strokeColor);
});

Categories