i'm trying to geocode values and map them to a satellite image of a city (new york city to be precise). i've successfully done this before using a geospatial image of the world, and then mapped/scaled longitude and latitude values from the max lat/lng range (-90,90 & -180,180) to the max width and hight of the image (0,width & 0,height) which worked perfectly. i'm a bit confused how to do this to just a map of a city.
currently, i have a hi-res satellite image of new york city, and have positioned it so that it perfectly aligns with the map of new york city on Google Maps (i'm using their API to geocode my locations). i've attempted to get the top/bottom latitude values and left/right longitude values of the satellite image i'm using, and tried to scale any longitude/latitude values that needed to be mapped onto the image within this range. however, this didn't seem to work. is there another method i could use so that it would be possible to dynamically map lat/lng coordinates onto a satellite image of new york city?
this is essentially the image that i would like to map onto:
thanks.
If you know the image size and its geographic extent (lat/lon values), you can use something like:
x = imageWidth * ( pointLon - ImageExtentLeft ) / (ImageExtentRight - ImageExtentLeft);
y = imageHeight * ( 1 - ( pointLat - ImageExtentBottom) / (ImageExtentTop - mImageExtentBottom));
By the way, if you are using the Google Maps API to geocode your locations, why don't you use its functions to add markers directly to your map? (Maybe I didn't completely understand your case)
var latlng = new GLatLng(pointLat, pointLon);
map.addOverlay(new GMarker(latlng));
Hope it helps
You are engaging in a process called image registration or map rectification. There is a whole set of remote sensing dedicated to the equations for doing this.
Perhaps you can just start with this web site - it should basically do what you need
http://labs.metacarta.com/rectifier/ (dead link)
if not then maybe look at tools like QGIS or GRASS. If you have money and time you can also use ESRI ArcGIS desktop or ERDAS Imagine or IDRISI.
Related
I have a GeoJson from brazil which is a more detailed version of the official HighMaps Brazil map. In this JSON I have the states divided into its mesoregions.
When I tried to draw a point on top of this GeoJson I got the message telling me that this functionality was only supported with official highmaps maps. Reading the documentation I found out that I should create an object hc-transform on my geojson. I thought it would make sense to use the same hc-transform used by the official HighMaps Brazil map, and when I did, it kinda works ok: It gives me the the same point with fromLatLonToPoint() method but then when I use the method toPixels() to get the "canvas" position (and draw something on top of it) it gives me different values.
The code Im using is this (it works fine for brazil official highmaps):
let point = chart.fromLatLonToPoint({lat: n.lat, lon: n.long});
let x = chart.xAxis[0].toPixels(point.x, true);
let y = chart.yAxis[0].toPixels(point.y, true);
// Draw the div / point / whatever on the (x, y) position
The GeoJson I am talking about you can find here: https://github.com/Menighin/HighmapsExperiment/blob/master/geo/mesorregiao.json
Checking Highmaps oficial Brazilian map I can see that each polygon also has some highcharts attributes (hc-middle-x, hc-middle-y, etc). Does that make any difference? If not, what am I doing wrong?
EDIT
Turns out my hc-transform doesn't seem to be right as we can see on this fiddle:
http://jsfiddle.net/0vm8a4x3/
If we uncoment the line 8, we can see that the city Belo Horizonte, is not plotted on the right position on the Mesoregion map.
So, how can I get the hc-transform right?
So I am working on a project that includes many uses placing annotations all around a map. The annotation, (which is a custom image with a much larger circular range) appears on the screen and, ideally, I would like for a user to be:
Notified if they are within the range of a annotation
and
Not be allowed to place another annotation within the range of another one if the circular pins overlap by, say, more than 25%
I think this is a pretty unique question and should be fun for somebody to help out with, so have fun! Thanks everybody!
You can check the distance from each annotation using
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
This method measures the distance between the two locations by tracing
a line between them that follows the curvature of the Earth. The
resulting arc is a smooth curve and does not take into account
specific altitude changes between the two locations.
For more details refer Link
Try this:
let location = CLLocation(latitude: 1, longitude: 1)//Or user's location
let distance = location.distance(from: anotherLocation)
Edit:
As mentioned in the comments, you wanted to create an equidistant point. I suggest manually doing that:
Subtract the annotation's location from he user's location. Then add your distance back to the original one. For example:
The user's location = (1, 1)
The annotation's location = (3, 2)
Vertical difference would be 2
Horizontal difference would be 1
Then:
(3 + 2, 2 + 1)
Your result: (5, 3)
Now you would have two points (the one you just created and the user's location) at each end with a center point (original annotation)
in my maps app i have to find the places (bank,ATM,cafe,bar..) inside bound of selected locations.Actually i have to get the places which are centre to the given locations.
for example i have 4 places a,b,c,d i have to get all banks inside bounds of these 4 places and have show them on map.
i can get nearest places for each location individually by using GooglePlaces API.but i need show places which are centre(approximately) to these 4 places.
please give me any suggestions how to do this or any example code or any other tutorials or links....
Thanks
Raki.
Your solution would be to take the average lat/lon of your points and then hit your Google API to get locations in that area. This average will be in the middle of however many coordinates you have. Example:
double totalLat = 0;
double totalLon = 0;
for(CLLocationCoordinate2D coordinate in coordinateArray)
{
totalLat += coordinate.latitude;
totalLon += coordinate.longitude;
}
// Use this average coordinate (which is the center of your points) to hit your Google API
CLLocationCoordinate2D averageCoordinate = CLLocationCoordinate2DMake(totalLat / coordinateArray.count, totalLon / coordinateArray.count);
Note: I haven't actually tested this, so don't just copy/paste, but it's the general idea.
You can always use the radius parameter defined in the Places API to get this information.
Please follow this Stack Overflow answer for more details.
The HERE Maps (the old Nokia Maps) has a variety of APIs, the most useful of which for non-web desktop applications looks like the Map Image API. This API allows you to specify a center location and a zoom level to get an image, along with an image size.
How do you georeference the returned image? The image is specified by center and zoom level, not by a bounding box or corner coordinates. If you need to display the map image as the background to other, geolocated data, how do find the coordinates of the image corners in order to render the map correctly?
My guess is that you can do so by using the zoom level, so, for example, a square image of any pixel size at a specific zoom level would have specific real-world dimensions. However, this is only a guess. The API documentation doesn't seem to have any content addressing georeferencing the map results at all.
The easiest way to do this would be to use the nomrk parameter and add two hidden poi markers for the top-left and bottom-right corners - as in this example of the Strait of Dover across the English Channel. [50N,2E - 51N,3E]
Ideally since the maps use the normalized Mercator projection, you should specify h and w to be the same value and keep the number of degrees latitude requested = number of degrees longitude requested. This will ensure that the POIs are in the corners of the map.
As an alternative, there is also the Map Tile API (log-in required), which uses standard Tile Map Service (TMS) addressing techniques. You can calculate the required tile using the following (sample code is in Java)
public void calculatePosition(int latitude, int longitude, int zoom) {
int p= Math.pow(2, zoom); double x= longitude /Math.PI; x=(x+1)/2;
double y= latitude/Math.PI; y = (log(tan(pi/4.0+latitude/2.0))+1)/2; y = 1 - y;
int column=(int) x*p; int row=(int)y*p;
System.out.println("[zoom,col,row] = " + zoom + "," + col+ "," + row);
}
I want to convert (google sourced) longitude and latitude coordinates to x and y to place points on a SVG map
I can get the longitude converted to X but I can't nail latitude.
http://jsfiddle.net/chrisloughnane/an3BZ/17/
red dots = place holders
green dot = calculated position from longitude/latitude
I have read so much about Mercator projections and other projection systems API's I am now completely confused. I also followed Proj4JS library threads but couldn't find an example that was close to my task.
I attempted to emulate this solution, unfortunately I got something wrong.
Could someone please have a look at my jsfiddle and see if it's an obvious mistake.
The second test function secondconvert(latitude, longitude) (bottom of javascript pane) provides me with a reasonably accurate x coordinate i.e. if I manually enter the y coordinate b.ylat change to 265 it covers my left red dot place holder nearly perfectly.
I think I'm close, any help would be really appreciated.
tia.
Original SVG from here.
In your calculations of lattest and mapOffsetY inside secondconvert() you're using variable width where Raphael's solution uses worldMapWidth. Fixing that you get closer to the expected result, though still not precise.