I need to implement a transformation from geographic coordinates with hight data to a image.
Like described in http://mathworld.wolfram.com/CylindricalProjection.html.
I simply don't know how to create the suitable y-value...
For example:
double longitude = -180; // (λ)
double latitude = 80; // (φ)
int mapHeight = 360;
int mapWidth = 720;
x = (int)((longitude+180.0)*(mapWidth/360.0));
How do i use the results of
Math.tan(Math.toRadians(latitude))
Thank you!
You can not represent the poles using a cylindrical projection. So you need to set a maximum latitude and store it (say double maxlat=3.1415/2.0). To get y, first, test if the point is not to close to the poles, then compute :
y=(int)(mapHeight/2+mapHeight/2*Math.tan(Math.toRadians(latitude)) /Math.tan(Math.toRadians(maxlat))) ;
If you are looking for a beautiful map, consider using the Mercator projection :
y=(int)(mapHeight/2+mapHeight/2*Math.log(Math.tan(Math.toRadians(latitude)/2.0+M_PI/4.0)) /Math.log(Math.tan(Math.toRadians(maxlat)/2.0+M_PI/4.0))) ;
Store Math.tan(Math.toRadians(maxlat)) or math.log(Math.tan(Math.toRadians(maxlat)/2.0+M_PI/4.0)) if you need to compute many points
Related
I am trying to distribute a number of points per acre within a square mile using Azure maps. Currently, I have been looking into the haversine formula, trig, basic division, etc, but believe I may be overthinking it.
Any ideas?
Lets say I want 3 points put per acre within a square mile in randomized but appropriate lat/lng locations within each acre.
Right now it seems I need to divide up the X and Y by feet or yard and then divide into the lat/lng to get appropriate locations.
A bit ignorant of lat/lng distances. The information I have found says that a degree of lat, for example, is worth about 69 miles. Then it divides it into "seconds," etc, apparently. A bit confusing.
Ideas?
A square with sides of 63.61 meters is equal to one acre. To calculate random points within that square, start off with a latitude and longitude coordinate for a corner, then calculate opposite corners coordinates, then calculate the latitude/longitude widths and use that to calculate random offsets from the starting coordinate. For example, take coordinate 45, -110 and assume this is the top left corner of the square. The opposite corner would have a heading of 135 degrees, and the distance to the corner would be sqrt(a^2 + b^2) = sqrt(63.61^2 + 63.61^2) = 89.9581247 meters. Here is code that would calculate three random points within that square acre.
var lat = 45;
var lon = -110;
var cornerDistance = 89.9581247;
var cornerHeading = 135;
//Bottom right corner.
var cornerPosition = atlas.math.getDestination([lat, lon], cornerHeading, cornerDistance);
var latWidth = lat - cornerPosition[1]; //Corner is lower.
var lonWidth = cornerPosition[0] - lon; //Corner is to the right.
var randomPositions = [];
for(var i=0;i<3;i++){
randomPositions.push(lon + Math.random()*lonWidth, lat - Math.random() * latWidth]);
}
I use the following code to get equirectangular texture coordinates based on an object's position in the world:
Equirec(positionX, positionY, positionZ) {
radius = sqrt(positionX^2 + positionZ^2);
a = atan2(-positionX, positionZ);
b = atan2(positionY, radius);
uv.x = (a - pi) / -2pi;
uv.y = (b + pi/2) / pi;
return uv;
}
Is it possible to invert this function?
What I want to do is, given the uv coordinates returned from this function, figure out the corresponding position in the world.
Not possible. You have thrown away information. The UV coordinates are within a single plane. If you knew the location of that plane in 3D space, you could do it.
I have an SQLITE database that stores the coordinates of places as float numbers.
PLACE TABLE
--------------------------------
placeID | latitude | longitude
--------------------------------
1 | XX.XXXXXX| YY.YYYYYY
2 | X1.XXXXXX| Y1.YYYYYY
Let's say that I'm standing in a place with specific coordinates (lat and lon).
I would like to find all the places 1km around me (in a circle).
1) How can I convert the meters to coordinates?
2) How can I get from the database all the places 1km away from me?
Cause I would like to add the meters to the coordinates.
Is that possible?
Thanks, in advance
Simply use the distanceTo() or distanceBetween(lat1, lon1, lat2, lon2) function of your API.
If you dont have such a method, then search for haversine formula.
Then the location are within a cirlcle of x meters around you if the distance from you to the object is <= x.
In code:
double radius = 1000; // 1 km
double distanceMeters = haversineDistance(mylat, mylon, otherLat, otherLon);
if (distanceeMeters <= radius) {
// other location (otherLat, otherfLOn) is inside of radius of 1km
}
I'm trying to translate latitude and longitude coordinates into coordinates of my own defined map. For instance:
51.876324 maps to 659.33 in my map
0.943395 maps to 2585.17 in my map other such examples might be:
51.875737 - 505.77
0.943564 - 2055.39
51.875883 - 1090.58
0.944658 - 1935.42
My math skills/knowledge is kind of rusted, but should I use substitution to find out what is the factor by which the coordinates can be mapped into mine?
Any hints are appreciated
Cheers!
It is not quite possible to answer this question exactly without knowing details about the map projection algorithm used. While lat and lon are angular coordinates on the earth (almost) ellipsoid the other seem to be map (x,y) coordinates.
If your map covers only a small part of the surface you might approximate this by a simple transformation
x = lon * factor_x + offset_x
y = lat * factor_y + offset_y
with constants factor_x, factor_y and offset_x and offset_y. From two distinct points on your map you may derive these constants by inversion:
factor_x = (x1-x2) / (lon1-lon2)
offset_x = x1 - lon1 * factor_x
and same for y.
I'm trying to find a way to calculate the area of a polygon using lat long coordinates in a Flex 3 site. Hong007 on Google Maps for Flash group was cool enough to post the following function:
private function GetPolygonArea (polygon : Polygon):Number
{
var nVer : int = polygon.getOuterVertexCount();
var sz : Number =0;
var s : Number =0;
var x : Number =0;
var y0 : Number =0;
var y1 : Number =0;
var Maplatlng:LatLng;
if (nVer>=3){
for (var i:int=0; i<nVer; i++){
Maplatlng = polygon.getOuterVertex(i);
x = Maplatlng.lng();
if (i>0){
Maplatlng = polygon.getOuterVertex(i-1);
y0 = Maplatlng.lat();
}
else{
Maplatlng = polygon.getOuterVertex(nVer-1);
y0 = Maplatlng.lat();
};
if (i<(nVer-1)){
Maplatlng = polygon.getOuterVertex(i+1);
y1 = Maplatlng.lat();
}
else{
Maplatlng = polygon.getOuterVertex(0);
y1 = Maplatlng.lat();
};
s = x * (y0-y1);
sz+=s;
};
//경위도시 1도의 m값을 곱한다(대략 면적 환산)
Maplatlng = polygon.getOuterVertex(0);
var Maplatlng1:LatLng = new
com.google.maps.LatLng(Maplatlng.lat()+1, Maplatlng.lng()+1);
var TempDISTANCE:Number =
Maplatlng.distanceFrom(Maplatlng1) / Math.sqrt(2);
return Math.abs((sz/2.0) * Math.pow(TempDISTANCE, 2));
};
return 0.0;
}
I was also playing around with the area calculator at http://www.freemaptools.com/area-calculator.htm .
These functions produce slightly different results. I'm trying to figure out which one is more accurate. It seems that hong007's function produces results that are on average slightly larger than freemaptools' function. However, I don't know which one is more accurate. Any advice?
I added some string to this algorithm.
For google maps experimentally I found this numbers:
are = area-(area*0.2187);
and it works for me for maximum (scale = 5 meters) and minimum (500 km) zoom levels.
The method implemented here is pretty quick and dirty. It makes a couple of assumptions that can lead to incorrect results.
The first thing to know is that Lat/Long space is non-uniformly scaled with respect to measured distance on the ground. This means that a vector of length one meter has a different length in lat/long space depending on if the vector is pointing roughly east-west or north-south. Also, the magnitude of the difference between how the lat/long axes map to ground units changes depending on where you are on the globe (it's much more different at the poles than at the equator.)
The algorithm above does a very quick and dirty workaround for this, which is to generate a scale value based on the distance calculated for the hypotenuse of a unit right triangle. This tries to basically average the scales of the two lat/long axes for that point on the globe.
There are a couple of problems with this. If the polygon is very large (multiple geocells), then this average scale value will be off because it's only calculated for the local geocell around the 0 vertex. Secondly, the average scale approximation is really very coarse and will break down significantly if you have polygons that vary greatly in one dimension but not the other (a long skinny polygon oriented along one of the axes). This is because the scale will be computed as an average of the scale of the two axes but one of the axes should have very little influence because of the distribution of the vertices.
I didn't look at the other area calculator but I would guess if you're seeing discrepancies that this code is the less accurate version.