2D Open Street Map Data Representation in Meters - gis

I am in the process of converting OSM data into an open source Minecraft port (written in javascript - voxel.js). The javascript rendition is written such that each voxel (arbitrarily defined as a cubic meter) is created as a relation from a single point of origin (x,y,z)(0,0,0).
As an example, if one wanted to create a cubic chunk of voxels, one would simply generate voxels as a relation to the origin (0,0,0) : [(0,0,0),(1,0,0), (0,1,0)...].
My question is this: I've exported OSM data, and the standard XML output (.osm) plots nodes in latitude and longitude. My initial thought is that I can create a map by calculating the distance of each node from an arbitrary point of origin (0,0,0) = (37.77559, -122.41392) using the Haversine formula, convert the distance to meters, find the bearing, and plot it as a relation to (0,0,0).
I've noticed, however, that there are a number of other export formats available: (.osm.pbf, .osm2pgsql, .imposm). I'm assuming they plot nodes in a similar fashion (lat, lng), but some of them have the ability to import directly into a database (e.g. PostgreSQL).
I've heard of people using PG add-ons like PostGIS, but (as this is my first dive into GIS) I'm unfamiliar with their capabilities and whether something like PostGIS would help me in plotting OSM data into a 2D voxel grid.
Are there functions within add-ons like PostGIS that would enable me to dynamically calculate the distance between two Lat/Lng points, and plot them in an x,y fashion?
I guess, fundamentally, my question is: if I create a script that plots OSM data into an x,y grid would I be reinventing the wheel, or is there a more efficient way to do this?

You need to transform from the spherical coordinates (LatLon, using WGS84) to cartesian coordinates, like googles spherical mercator.
In pseudo code
transform(double lat, double lon) {
double wgs84radius = 6378137;
double shift = PI * wgs84radius;
double x = lon * shift / 180;
double y = log(tan((90+lat)*PI/360)/ (PI/180);
return {x,y}
}
This is the simplest way. Keep in mind that Lat/Lon are angles, while x and y are distances from (0/0)

The OSM data is by default in the WGS84 (EPSG:4326) projection which is based on an ellipsoidal Earth and measures latitude and longitude in degrees.
Most map tiles are generated in the EPSG:900913 "Google" spherical mercator projection. This projection is based on a spherical Earth and latitude and longitude are measured in metres from the origin.
It really seems like the 900913 projection will fit quite nicely with your requirements.
Here is some code for converting between the two.
You might like to consider using osm2psql. During the import process all of the OSM map data is converted to the 900913 projection. What you are left with is a database of all the nodes, lines and polygons of the OSM map data in an easy to access Postgres database.
I was initially intimidated by this process but it is really quite straightforward and will give you lots of flexibility when it comes to using the OSM data.

Related

How to convert attribute table fields in WGS84 meters to fields in decimal degrees in QGIS

I have fields where location data is in X- and Y columns in WGS84 meter-format. How can I convert these fields or create new fields with decimal degrees? Vector->Geometry Tools-> Export/Add geometry columns creates duplicate fields with the same meter-format. Similarly using field calculator with $x- and $y functions creates also fields with meter-formats.
I may be misinterpreting the question, but WGS84 is a geographic coordinate system, utilizing the WGS84 ellipsoid, its coordinate space is measured as lat long pairs and not meters. See unit of measurement here or here. As such WGS 84 is not represented as meters, see discussion here, here or here (comments). In short, WGS84 uses angular measurements to represent the locations within a three dimensional space, as a metered grid doesn't envelope the earth very well. WGS84 is always projected when displayed in GIS software (without changing the underlying data), it is projected to convert it from a 3 dimensional representation of the earth to a 2 dimensional.
Your data, if measured in meters, is projected. The WGS84 ellipsoid may be used as part of the basis of a projection, such as with UTM or WGS84 Antarctic Polar Stereographic. The projection you have and its parameters are critical to understanding how you determine the position of a point in degrees, as a point will essentially have to be unprojected to get its latitude and longitude.
Luckily this is relatively easy in GIS software.
In QGis you can change the coordinate reference system of your layer to WGS 84 (EPSG:4326) - which it could be already with the data coming from a different source or previous CRS - and then use the field calculator to calculate the geometry that you are looking for (assuming that your fields in meters represent something that can be calculated by the field calculator). This also requires your existing data to have a defined projection. If needed you can convert back after you have added the new data.
In Arc, the process is largely the same, using the "project" tool to reproject/unproject the data.
If your data layer does not have a defined projection, you will need to find it. If your data layer fields that are already in meters are not something easily calculated from the field calculator in qGIS, then it might get a little more involved (creating a layer from those fields, changing the CRS of that layer, calculating the fields in degrees...).

Given two point's latitude and longitude, computing coordinates of point in between

I'm trying to generate some annotations on a map. Currently, I'm using openstreetmap but the query is general. I have two end points on a map and a corpus of few selected points I would like to highlight.
The two endpoints are given in the form lat, long
<walkSteps>
<distance>9.742464221826811</distance>
<streetName>5th St NW</streetName>
<absoluteDirection>EAST</absoluteDirection>
<stayOn>false</stayOn>
<bogusName>false</bogusName>
<lon>-84.3937361115149</lon>
<lat>33.77692965678444</lat>
<elevation/>
</walkSteps>
<walkSteps>
<distance>508.2608917548245</distance>
<relativeDirection>LEFT</relativeDirection>
<streetName>Fowler St NW</streetName>
<absoluteDirection>NORTH</absoluteDirection>
<stayOn>false</stayOn>
<bogusName>false</bogusName>
<lon>-84.39363494600667</lon>
<lat>33.77692904176358</lat>
<elevation/>
</walkSteps>
My aim is to highlight those points on the map, which are present in the corpus and lie in the line connecting these two points.
How can I go about querying the corpus for the same? Annotating on map given lat, lng is not an issue
Rounding errors will prevent you from directly doing as you want. What you should be doing instead is determining the great-circle path between the two end points and highlighting those members of the corpus which are within a certain distance of the great circle route. This is known as the cross-track distance or cross-track error. Formulas for computing the cross-track distance can be found at one of the standard reference sites for geospatial equations but there are others as well.. The problem then becomes one of searching for points in the corpus which are close enough to the great circle path between the two end points.

convert meters to latitude longitude from any point

In my project I have to find [latitude, longitude] coordinate(s) from one point in distance of 500 meters (this could be any random coordinate or an array of coordinates around my point). How can I do this?
Note: I need this in order to find multiple paths between points different from shortest one which is returned us via Google Maps Directions Api..So using my method I will define the center of the road from A to B and then find some coordinates below and above that center position and use this as another waypoint to go from A to B - I guess this might help me to find multiple paths...
Any suggestions from GIS professionals?
EDIT: UTM conversion is the most preferable one for such calculations, and I've created UTM Java class if anyone needs..
If I understand your question right you have a known point in Lat/Long and you need calculate the Lat/Long of another point or points 500m away from your starting point.
If this is what you are doing, you have several options most of which involve specialist GIS APIs. However, I'm guesing you're a programmer/mathematician rather than a Geographer so, you may prefer to opt for using the Haversine formula. You can find a discussion on this topic here plus the formula.
One caveat is that the distamce you are working with (500m is quite small) and the Earth is far from being a perfect sphere or even a slightly flattened spheroid. It is locally "lumpy" and that can put your calculation out. If you need more accuracy you will have to account for these imperfections by using an appropriate local Datum (model of the Earth - there are many e.g. see EPSG list) and to do that you will probably need to start using the GIS libraries as the maths gets very detailed otherwise.
This is the code used by google map (SphericalUtil.java)
// from SphericalUtil.java
// compile 'com.google.maps.android:android-maps-utils:0.4.4'
public static LatLng computeOffset(LatLng from, double distance, double heading) {
distance /= 6371009.0D; //earth_radius = 6371009 # in meters
heading = Math.toRadians(heading);
double fromLat = Math.toRadians(from.latitude);
double fromLng = Math.toRadians(from.longitude);
double cosDistance = Math.cos(distance);
double sinDistance = Math.sin(distance);
double sinFromLat = Math.sin(fromLat);
double cosFromLat = Math.cos(fromLat);
double sinLat = cosDistance * sinFromLat + sinDistance * cosFromLat * Math.cos(heading);
double dLng = Math.atan2(sinDistance * cosFromLat * Math.sin(heading), cosDistance - sinFromLat * sinLat);
return new LatLng(Math.toDegrees(Math.asin(sinLat)), Math.toDegrees(fromLng + dLng));
}
to use it, you just have to enter the centerLatLng, the distance in meters, and the heading in degrees from centerLatLng.
you can change the formula to the language of your preference.

Mysql geometry AREA() function returns what exactly when coords are long/lat?

My question is somewhat related to this similar one, which links to a pretty complex solution - but what I want to understand is the result of this:
Using a Mysql Geometry field to store a small polygon I duly ran
select AREA(myPolygon) where id =1
over it, and got an value like 2.345. So can anyone tell me, just what does that number represent seeing as the stored values were long/lat sets describing the polygon?
FYI, the areas I am working on are relatively small (car parks and the like) and the area does not have to be exact - I will not be concerned about the curvature of the earth.
2.345 of what? Thanks, this is bugging me.
The short answer is that the units for your area calculation are basically meaningless ([deg lat diff] * [deg lon diff]). Even though the curvature of the earth wouldn't come into play for the area calculation (since your areas are "small"), it does come into play for the calculation of distance between the lat/lon polygon coordinates.
Since a degree of longitude is different based on the distance from the equator (http://en.wikipedia.org/wiki/Longitude#Degree_length), there really is no direct conversion of your area into m^2 or km^2. It is dependent on the distance north/south of the equator.
If you always have rectangular polygons, you could just store the opposite corner coordinates and calculate area using something like this: PHP Library: Calculate a bounding box for a given lat/lng location
The most "correct" thing to do would be to store your polygons using X-Y (meters) coordinates (perhaps UTM using the WGS-84 ellipsoid), which can be calculated from lat/lon using various libraries like the following for Java: Java, convert lat/lon to UTM. You could then continue to use the MySQL AREA() function.

lat long intersection

I have two sets of "lines" drawn using a mapping API in the form of (lat,long) pairs. Given 2 of these lines, how can I compute the (lat, long) of their intersection (assuming they intersect)?
Depends on what coordinate system you're in.
You'll need the geodesic along the surface of the model you're using for each line segment (you can choose any convenient altitude you want since you only care about lat and long). Then the point that's on both geodesics (if it exists) is your answer. Note also that one geodesic may be coincident with the other (superimposed).
Since you're using the Mercator projection, you can translate the lat and long to X and Y on your map, then solve for their intersection easily.