Determine the lat lngs of markers within a polygon - google-maps

I have a google maps app which plots markers as it loads. One of the new requirment is to to add a Polygon overlay encompassing a selection of markers by the user. I was able to achieve that using the Geometry Controls of the GMaps Utility Library
Now, the next step is to form a group of the selected markers for which I would need to determine if the lat lngs of the markers falls within the lat lngs of the polygon? Is there a way to determine the lat lngs of a polygon and compute if the marker's lat lng is within its boundaries?

I have never directly messed around with Google Maps, but you can store the points that make up the polygon and then use the Point-In-polygon Algorithm to check if a given longitude and latitude point is within a polygon or not.

// Create polygon method for collision detection
GPolygon.prototype.containsLatLng = function(latLng) {
// Do simple calculation so we don't do more CPU-intensive calcs for obvious misses
var bounds = this.getBounds();
if(!bounds.containsLatLng(latLng)) {
return false;
}
// Point in polygon algorithm found at http://msdn.microsoft.com/en-us/library/cc451895.aspx
var numPoints = this.getVertexCount();
var inPoly = false;
var i;
var j = numPoints-1;
for(var i=0; i < numPoints; i++) {
var vertex1 = this.getVertex(i);
var vertex2 = this.getVertex(j);
if (vertex1.lng() < latLng.lng() && vertex2.lng() >= latLng.lng() || vertex2.lng() < latLng.lng() && vertex1.lng() >= latLng.lng()) {
if (vertex1.lat() + (latLng.lng() - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < latLng.lat()) {
inPoly = !inPoly;
}
}
j = i;
}
return inPoly;
};

Following npinti's suggestion, you may want to check out the following point-in-polygon implementation for Google Maps:
Check if a polygon contains a coordinate in Google Maps

This has been updated in v3. You can do this calculation via the google.maps.geometry.poly namespace API Documentation

Related

google maps polygon on click , show summary of markers within the polygon

Need some help with google maps polygon areas. I have a many markers plotted across the google map. Have some polygon areas plotted on map too. I want to find the total of marker points covered by a polygon, whenever the polygon area is clicked. Kindly guide or provide some good links in this direction
Thanks.
You could try ray casting algorithm. The implementation would be something like this:
var markers = []; // list of your markers
var polygonPath = polygon.getPath();
var location;
for (var i = 0; i < markers.length; i++) {
location = markers[i].getPosition();
console.log(isPositionInside(location.lat, location.lng, polygonPath));
}
function isPositionInside(mLat, mLng, polygonPoints) {
var isInside = false;
for (var a = 0, b = polygonPoints.length - 1; a < polygonPoints.length; b = a++) {
var aLng = polygonPoints[a].lng,
aLat = polygonPoints[a].lat,
bLng = polygonPoints[b].lng,
bLat = polygonPoints[b].lat;
if ((aLng > mLng) != (bLng > mLng) && (mLat < (bLat - aLat) * (mLng - aLng) / (bLng - aLng) + aLat)) {
isInside = !isInside;
}
}
return isInside;
};
This isn't the most optimal solution, as you can read in the wiki article, but in most cases it will get the job done.

Google Static Map Tile Location

I'm trying to use something other than latitude and longitude for the Google staticmap center location. I would prefer pixel or tile coordinates. After reading the docs, it does not appear they support anything other than lat & lng.
What I am trying to do is display a series of static maps placed next to each other. I have everything working. However, using the longitude to offset the next staticmap in the sequences seems to offset it in the lat by a little bit. Meaning, if I only update the lng value it appears to shift in the lat as well.
In some cases, the image will not offset until a substantial change has been made to the lng.
Example Code:
var lat = 40.714728;
var lng = -73.998688;
var size = 640;
for(var i = 0; i < 2; ++i)
{
var addressLatLng = "("+lat+","+lng+")";
var google_tile = "http://maps.google.com/maps/api/staticmap?sensor=false&center="+addressLatLng+"&zoom=20&size="+size+"x"+size+"&maptype=satellite";
lng += 0.0005; // Does not shift up/down if using 0.0001 but also creates repeated visual data... needs a seamless transition from one tile to the next.
}
Is there a better approach for what I am trying to do?

Maps google-apps-script info using distances along a route/path

I am trying to figure out a way to show items using the map script with the following info:
10 miles north running along US 1 plot a marker 10 feet to the right(east) of US 1. And to set for example that mile 0 starts at the intersection between US 1 and Main Street.
Perhaps someone has run into this before or something similar and will be kind enough to give me some pointers.
Thanks!
Following Eric's tip I was able to create a function to grab a polyline for the road centerline from Google Maps. Then use the google api service to convert that polyline into latitude and longitude coordinates. From then on, it was all spherical geometry coding. Below is my humble little code:
//Function to grab a centerline from the Map Api
//start = lat and long for beginning of roadway centerline ie [27.64681, -82.38438]
//end = lat and long for end of roadway centerline ie [27.71248, -82.33518]
//startmile = beginning milepost
function grabmap(start, end, startmile){
startmile = parseFloat(startmile);
var points = [];
var plinex = [];
var pliney = [];
var directions = Maps.newDirectionFinder().setOrigin(start).setDestination(end).getDirections();
// Much of this code is based on the template referenced in
// http://googleappsdeveloper.blogspot.com/2010/06/automatically-generate-maps-and.html
for (var i in directions.routes) {
for (var j in directions.routes[i].legs) {
for (var k in directions.routes[i].legs[j].steps) {
// Parse out the current step in the directions
var step = directions.routes[i].legs[j].steps[k];
// Call Maps.decodePolyline() to decode the polyline for
// this step into an array of latitudes and longitudes
var path = Maps.decodePolyline(step.polyline.points);
points = points.concat(path);
}
}
}
var lengthvector = (points.length / 2);
for ( i = 0; i <= points.length; i++){
if ( i % 2 == 0){
plinex = plinex.concat(points[i]);
pliney = pliney.concat(points[(i+1)]);
}
}
var plineVector = new Array(plinex.length - 2);
for ( i = 0; i <= plinex.length - 2; i++){
plineVector[i] = new Array(2);
plineVector[i][0] = plinex[i];
plineVector[i][1] = pliney[i];
}
return plineVector;
}
I haven't used the Maps Service extensively, but it should be possible. You use the DiretionFinder to get the latitudes and longitudes of points along the path, and then do some math to get the offset for the marker.

Google map Draggable PolyLines

I am having a map with some polylines with the distance [api v3]. I want that when someone drag the polyline at the same time the distance also get updated but dont know how to do. Please help me, any good tutorial or another threads are most welcome
Thanks for helping me
Naveen
This page describes using draggable markers and updating the distance when a marker is moved.
http://exploregooglemaps.blogspot.com.br/2012/02/measuring-distance-with-markers.html
There is a attribute which makes your polyline editable.
polyPath.setEditable(true);
Now use a listener to check the editing.
google.maps.event.addListener(polyPath, 'capturing_changed', function() {
var array = polyPath.getPath(); //getPath() gives u array of current markers latlng over map
var tempDistance = 0;
var tempPathArray = [];
for(i = 0; i < array.length; i++){
tempPathArray.push(array.getAt(i));
}
for(k = 1; k < tempPathArray.length; k++)
{
var calculateNewDistance=google.maps.geometry.spherical.computeDistanceBetween(tempPathArray[k-1],tempPathArray[k]);
tempDistance += calculateNewDistance;
}
}
// make sure to add the following script to compute the distance between two latlngs

Convert lat/lon to pixels and back

I'm using google maps in my application, and I have a webserver with a databse filled with lat/lon values. I want to mark them on the map, but I also want to cluster them together if they are within a certain pixel-distance of eachother.
I figure if I retrieve all my points from the database, I should be able to do something like this (pseudocode):
clusters[];
while(count(points)) {
cluster[];
point = points.pop();
boundingbox = pixelsToBB(point, pixeldistance, zoomlevel);
query = "select * from database where lat > boundingbox.minlat
and lat < boundingbox.maxlat and lng > boundingbox.minlng
and lng < boundingbox.maxlng";
for (result in executedquery) {
cluster[] += result;
points.remove(result);
}
clusters[] += cluster;
}
pixelsToBB(point, distance, zoomlevel) {
center = convertXY(point, zoomlevel);
maxlng = convertToLng(center.X, distance, zoomlevel);
minlng = convertToLng(center.X, -distance, zoomlevel);
minlat = convertToLat(center.Y, -distance, zoomlevel);
maxlat = convertToLat(center.Y, distance, zoomlevel);
return boundingbox(maxlng, maxlat, minlng, minlat);
}
What would my pixelsToBB function need to do with the zoomlevel? OR rather what would my convertToXY, convertToLng and convertToLat need to do? Am I thinking about this the right way, or are there any better ways to do it?
I'm not even sure what to search for, so if it's been asked before I'm sorry.
Using Google Maps API v3:
var latLng = // your position object here
var projection = map.getProjection();
var bounds = map.getBounds();
var topRight = projection.fromLatLngToPoint(bounds.getNorthEast());
var bottomLeft = projection.fromLatLngToPoint(bounds.getSouthWest());
var scale = Math.pow(2, map.getZoom());
var worldPoint = projection.fromLatLngToPoint(latLng);
return [Math.floor((worldPoint.x - bottomLeft.x) * scale), Math.floor((worldPoint.y - topRight.y) * scale)];
There is a JavaScript example to do this on this page as part of the documentation for the Google Maps API. Bear in mind you need to look at the page source to see it. It's not an actual documentation page but rather an example.