Google Static Map Tile Location - google-maps

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?

Related

Get Google Map Marker Position on Screen

Is there a way to get the bounding rectangle (screen position) of Google Map API markers? I am using an Angular 2 wrapper, so I don't construct the markers like you would normally with the API (mostly irrelevant here though).
Or are they on an internal canvas with no way to pull position like you would with an html element?
I have tried something like this, but getBoundingRectangle() comes back with zero values:
var googleMapContent = document.getElementsByClassName("sebm-google-map-content")[0];
var markerList = googleMapContent.getElementsByTagName("sebm-google-map-marker");
if( markerList.length > 0 ) {
for (var i = 0; i < markerList.length; i++ ){
var marker = markerList[i];
var markerLabel = marker.getAttribute("ng-reflect-label");
var boundingRectangle = marker.getBoundingClientRect();
}
}
P.S. I have access to map center lat/lng + zoom and marker lat/lng, so I can "math" this, but that's pretty dirty.
The Marker class hasn't got either a getBoundingRectangle or
getBoundingClientRect method.
It has got getPosition() and getShape() though, which in combination might give you the information you need.

Find near by places of specific angle - consider only half circle of front not the back in round circle query

I know how to find near by locations from MySQL database using Round circle radius query and I have given answer of the same on another SO question as well here.
But I wish to do some different thing from this now. Here what happened is the query returns the result from center of the point which includes entire circle of radius. I wish to get points only of the half circle. I know this is possible and its all mathematical calculation and I am little weak in it that's why asking for experts help.
See this image, it will give very clear idea.
As you can see in the image only front part location is needed, not the back side part. Need to ignore the back side part. Also I have divided the radius in different color to make them appear as zones - like red is zone1, orange is zone 2 and yellow is zone 3. This are virtual zones to filter the data (locations).
All suggestions are welcome.
You can plot points inside a segment using Haversine/Spherical Law of Cosines for the radius. Then use pointInPolygon() to find only those within segment. You will also require function to create polygon.
polySides = number of sides in polygon
pointLatArr = Lat of point in in polygon array
pointLngArr = Lng of point in in polygon array
dat.lat = Lat from Haversine results
dat.lng = Lng from Haversine results
if (pointInPolygonpolySides,pointLatArr,pointLngArr,dat.lat,dat.lng)){
var latlng = new google.maps.LatLng(dat.lat,dat.lng);
addMarker(latlng,dat.name);
bounds.extend(latlng);
}
function pointInPolygon(polySides,polyX,polyY,x,y) {
var j = polySides-1 ;
oddNodes = 0;
for (i=0; i<polySides; i++) {
if (polyY[i]<y && polyY[j]>=y || polyY[j]<y && polyY[i]>=y) {
if (polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x) {
oddNodes=!oddNodes;
}
}
j=i; }
return oddNodes;
}
Function for segment polygon
function drawSegment(start,end,radius) {
var d2r = Math.PI / 180;
pointLatArr = new Array();
pointLngArr = new Array();
polyLatLngs = new Array(); // latLngs of polygon
var polyLat = (radius /3963.189) / d2r; // miles
var polyLng = polyLat / Math.cos(center.lat() * d2r);
var centerLatLng = new google.maps.LatLng(center.lat(),center.lng());//Center to start
pointLatArr.push(center.lat());
pointLngArr.push(center.lng());
polyLatLngs.push(centerLatLng);
bounds.extend(centerLatLng);
// Create polygon points (extra point to close polygon)
for (var i = start; i < end; i++) {
// Convert degrees to radians
var theta = i * d2r;
var pointLat = center.lat() + (polyLat * Math.sin(theta));
var pointLng = center.lng() + (polyLng * Math.cos(theta));
var pointLatLng = new google.maps.LatLng(
parseFloat(pointLat), parseFloat(pointLng));
polyLatLngs.push(pointLatLng);
pointLatArr.push(pointLat);
pointLngArr.push(pointLng);
bounds.extend(pointLatLng);
}
var centerLatLng = new google.maps.LatLng(center.lat(),center.lng());//End to center
polyLatLngs.push(centerLatLng);
pointLatArr.push(center.lat());
pointLngArr.push(center.lng());
polySides = polyLatLngs.length;
Map using this technique
}
See Demo

Convert (x, y) pixel coordinates in google.maps.Point

I am trying to find out the LatLng based on my x,y pixel coordinates (and of course map options, such as zoom and center).
In order to do so, I posted another question and someone came up with this solution, from this post:
/**
* #param {google.maps.Map} map
* #param {google.maps.Point} point
* #param {int} z
* #return {google.maps.LatLng}
*/
var pointToLatlng = function(map, point, z){
var scale = Math.pow(2, z);
var normalizedPoint = new google.maps.Point(point.x / scale, point.y / scale);
var latlng = map.getProjection().fromPointToLatLng(normalizedPoint);
return latlng;
};
As you can notice from the code sample, the function uses as argument a google.maps.Point, therefore I need to convert my screen pixel coordinate into a google.maps.Point and I have no clue how, since their documentation of the API is not quite verbose...
Can you please help me? Or am I missing something on the way?
After some research and some fails I came up with a solution.
Following the documentation from this link I found out that the google Points are computed in the range of x:[0-256], y:[0-256] (a tile being 256x256 pixels) and the (0,0) point being the leftmost point of the map (check the link for more information).
However, my approach is as it follows:
having the x and y coordinates (which are coordinates on the screen - on the map) I computed the percentage where the x and y coordinates were placed in response to the div containing the map (in my case, the hole window)
computed the NortEast and SouthWest LatLng bounds of the (visible) map
converted the bounds in google Points
computed the new lat and lng, in google points, with the help of the boundaries and percentage of x and y
// retrieve the lat lng for the far extremities of the (visible) map
var latLngBounds = map.getBounds();
var neBound = latLngBounds.getNorthEast();
var swBound = latLngBounds.getSouthWest();
// convert the bounds in pixels
var neBoundInPx = map.getProjection().fromLatLngToPoint(neBound);
var swBoundInPx = map.getProjection().fromLatLngToPoint(swBound);
// compute the percent of x and y coordinates related to the div containing the map; in my case the screen
var procX = x/window.innerWidth;
var procY = y/window.innerHeight;
// compute new coordinates in pixels for lat and lng;
// for lng : subtract from the right edge of the container the left edge,
// multiply it by the percentage where the x coordinate was on the screen
// related to the container in which the map is placed and add back the left boundary
// you should now have the Lng coordinate in pixels
// do the same for lat
var newLngInPx = (neBoundInPx.x - swBoundInPx.x) * procX + swBoundInPx.x;
var newLatInPx = (swBoundInPx.y - neBoundInPx.y) * procY + neBoundInPx.y;
var finalResult = new google.maps.Point(newLngInPx, newLatInPx);
You could use an overlay that draws nothing in order to get at the super valuable function, fromContainerPixelToLatLng()
var overlay = new google.maps.OverlayView();
overlay.draw = function() {}; // empty function required
overlay.setMap(map);
var coordinates = overlay.getProjection().fromContainerPixelToLatLng(
new google.maps.Point(x, y)
);
console.log(coordinates.lat + ", " + coordinates.lng);

Can I reset latlng coordinates for a custom map type?

I have made my own map using the google maps api. It is a custom map type based on a really big image.
Is there anyway I can reset the latlng coordinates so they are relative to my image and not the earth's default latlng coordinates?
I.E. Make the top left corner of the image (0,0).
Thanks.
Yes, it's possible with your own custom projection definitions. I modified this lunar surface example with a simple projection that takes the top-left corner to be (0,0) and bottom-right, (50,50). You will most likely need to change the values to work with your app.
I played around a bit with the limits and there looks to still be a hard limit of +/- 90 for latitudes and +/- 180 for longitudes. The longitude will wrap around at 180 degrees. That is, it appears to be impossible to define a custom coordinate of, say, (100, 200).
See the modified lunar surface demo here, click anywhere to display the custom latLng in an alert:
http://jsfiddle.net/yV6xv/79/
function percentProjection() {};
percentProjection.prototype.fromLatLngToPoint = function(latlng) {
// pixel size of tile at zoom 0
var max = 256;
// define bottom-right corner as (50, 50)
var x = max * latlng.lng() / 50;
var y = max * latlng.lat() / 50;
return new google.maps.Point(x, y);
};
percentProjection.prototype.fromPointToLatLng = function(pixel) {
// inverse conversion
var max = 256;
var lng = pixel.x / max * 50;
var lat = pixel.y / max * 50;
return new google.maps.LatLng(lat, lng);
};

Determine the lat lngs of markers within a polygon

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