PostGIS: Linestring length - postgresql

I am using PostGIS to calculate length of a user-defined linestring. The column is defined as geography(LineString,4326).
The linestring is represented by this GeoJSON:
"track": {
"type": "LineString",
"coordinates": [
[
49.364325571013,
16.785549033597
],
[
49.363254969491,
16.642149334451
]
]
}
SELECT ST_Length("geography") FROM table; returns 15945.7486086962 but the length measured on Google Maps is ~10 km.
What am I doing wrong? How to measure the length to get the same value as from Google Maps?

I believe it is the classic issue of switching x,y positions.
Considering x,y:
SELECT
ST_Length(
ST_GeogFromText('SRID=4326;LINESTRING(49.364325571013 16.785549033597,49.363254969491 16.642149334451)'),true);
st_length
------------------
15869.9069442778
and the "same" LineString switching to y,x ..
SELECT
ST_Length(
ST_GeogFromText('SRID=4326;LINESTRING(16.785549033597 49.364325571013,16.642149334451 49.363254969491)'),true)
st_length
------------------
10416.8606521809

Figured out the problem.
I was using ST_GeomFromText('LINESTRING(lat lon, lat lon)') to create the line. The correct order is lon lat, so ST_GeomFromText('LINESTRING(lon lat, lon lat)').
GeoJSON uses the same order of coordinates: 49.363254969491 = latitude, 16.642149334451 = longitude.
The reason I didn't realize this was because I used Leaflet to draw the line. I basically took the points by geoJSON.getLayers()[0].feature.geometry.coordinates and passed them to a Polyline object. It created the Polyline points by taking the first coordinate from the GeoJSON as Lat, the second as Lng. This way it got reversed the second time and got rendered correctly.
So after switching lon lat in the query I had to use L.GeoJSON.coordsToLatLngs() function to correctly render the line.

Related

Convert coordinate between projections of different bounds

I have markers that were plotted in a legacy system on a EPSG4326 map with a bounds of -180 to 180 latitude and -180 to 180 longitude. I'm now trying to plot these onto a EPSG4326 map that has a bounds of -90 to 90 latitude and -180 to 180 longitude. How can I convert the original coordinate to the new coordinate system so it appears on the new map at the same location? I'm trying to tackle this within a JavaScript application using the Leaflet mapping library. Any pointers or insight would be greatly appreciated.
As an example, the location of London on the source map that represents latitude in -180 to 180 range is approximately (Lat: 61.8750, Lon: 0.1278) and on destination map where latitude is -90 to 90 it would be about (Lat: 51.5074, Lon: 0.1278).
I figured it out!
newlat = (180.0/Math.PI*(2.0*Math.atan(Math.exp(oldlat*Math.PI/180.0))-Math.PI/2.0))
Thus if oldlat = 61.8750, newlat = 52.482780222078226 which is what I needed and solves my problem perfectly, converting a latitude with different extents into the new extents.
The reverse (if needing to reconvert) formula is:
oldlat = ((180.0/Math.PI)*Math.log(Math.tan((90.0+newlat)*Math.PI/360.0)))

Is there any way to check whether a google map polygon or circle area is greater than the earth hemisphere

Is there any way to check whether a google map polygon or circle area is greater than the earth hemisphere so that we can know the geowithin queries will not work properly in mongo queries Link.Or what is the condition where the geo spatial query works perfect.
{
<location field>: {
$geoWithin: {
$geometry: {
type: <"Polygon" or "MultiPolygon"> ,
coordinates: [ <coordinates> ]
}
}
}
}
For egs: Area of a polygon can be calculated by:
google.maps.geometry.spherical.computeArea(e.getPath())
where e is the event object varible when the polygon completed event. but how can we compare those with the earth hemisphere area?
how can we compare those with the earth hemisphere area?
Provided that the Earth radius is about 6371 km, you can just calculate the spherical surface area of the hemisphere:
A = 2πr^2
A = 2π(6371)^2
A = 255032236 square km
If the result of google.maps.geometry.spherical.computeArea(e.getPath()) is greater than the above value, then the area polygon/circle is greater than one of the Earth's hemisphere.

Store circle on earth

I want to store in table places defined by coordinate (41.67102,72.917482) and radius 100 metes. How can I convert 100 metes in same measure as coordinates because 1 latitude != 1 longitude. Or I should use postgis somehow?
In postgis, the circle would be calculated with something like:
update PLACES set the_circle = (ST_Buffer((place_geom)::geography, 100 ))::geometry) ;

Basemap - request values from NOAA Data

I am working on this script and need to query the data object that I get through netCDF4 (first example) to retrieve values at a specific latitude and longitude coordinate. I am not sure how to index the data object in the example with lat/long in degrees or how to map coordinates onto a meshgrid and query from there. Ideas anyone?
Based on the NOAA sample script and with the help of the ww3 mail list, I figured this:
In order to get values from the data object, you do
from mpl_toolkits.basemap import Basemap,interp
lat = GPSLat
lon = (360 + GPSLon)
value = interp(data, lon, lat, np.asarray( [[ (360+ GPSLon) % 360 ]] ), np.asarray( [[ GPSLat ]] ), checkbounds=True, masked=True, order=1)

Can I transform the embedded interactivity coordinate system result from lat lon to epsg 3857 (web mercator)?

When using the embedded interactivity embedded interactivity function on the iOS SDK I can click a map tile and get the data coords in LAT LON but I would like to have the result in EPSG 3857 WGS 84...is this possible? If so what is the transform command?
Looks like I am going to answer my own question. I could not find a transform function. So I passed the LAT LONG coordinate pair to the webservice and did the transformation on the server.
You can do this with Leaflet/Mapbox.
Here's an example
var latlng = L.latLng(45, -120);
var sphericalMercator = L.Projection.SphericalMercator.project(latlng);
sperhicalMercator.x => -2.0943951023931953
sphericalMercator.y => 0.8813735870195429
You'll still need to multiply these coordinates by 6378137 (earth's radius in meters) (why Leaflet doesn't do this, I don't know...), and you get the spherical mercator equivalent to the original lat/long (45, -120):
(-13358338.8952, 5621521.48619)