PostGIS st_centroid but return as kml - postgis

SELECT
st_centroid(the_geom), roads."id" FROM
"public".roads
How would I do the centroid but return it as kml?
basically I want the center of the line string cords and the name of the road.
And is there a way to return lat long of the road centroid as x & y

SELECT ST_AsKML(ST_Centroid(the_geom)),id FROM roads

Related

SQL Server Polygon format

SELECT TOP 1 KMLLocation FROM Polygon
Result: 0xE61000000104210000004ACE893DB4BF19403EB2B96A9EFF534082919735B1C0194039807EDFBFFF534052F17F4754C81940976F7D586F0054405AD76839D0D31940AED3484BE50054409E961FB8CAD3194087BF266BD40054403F90BC7328D3194071C806D2C5005440844A5CC7B8D21940E4D70FB1C100544014CE6E2D93D1194062BF27D6A90054404FB2D5E594D01940E27668588C005440E910381268D01940E7E26F7B820054409AEAC9FCA3CF1940A54E4013610054409432A9A10DD01940CD902A8A5700544015E126A3CAD01940FE0E45813E0054407FBDC282FBD11940C30DF8FC30005440EB1B98DC28D2194038312427130054403065E08096CE19404A7CEE04FBFF534082035ABA82CD1940C2F7FE06EDFF5340462234828DCB19409373620FEDFF534031B2648EE5CD1940E338F06AB9FF5340CFDC43C2F7CE1940321EA5129EFF5340B98C9B1A68CE194055A3570394FF5340A8E15B5837CE1940639CBF0985FF53403868AF3E1ECA1940001FBC7669FF534029CB10C7BAC81940ED9C668176FF5340C6DB4AAFCDC61940AD18AE0E80FF534047CCECF318C51940F390291F82FF5340EDB776A224C41940FD851E317AFF5340E4F90CA837C31940C440D7BE80FF5340DF1AD82AC1C21940462234828DFF53409C69C2F693C1194007D2C5A695FF5340C5387F130AC119406AFB57569AFF5340D1E7A38CB8C01940574277499CFF53404ACE893DB4BF19403EB2B96A9EFF534001000000020000000001000000FFFFFFFF0000000003
SELECT TOP 1 KMLLocation .ToString() FROM Polygon
Result:
POLYGON ((79.994044 6.437211, 79.996086 6.438176, 80.006796 6.445634, 80.013995 6.456849...
Expected Result:
POLYGON ((6.437211 79.994044, 6.438176 79.996086, 6.445634 80.006796, 6.456849, 80.013995...
How do I swap Lat and Long from geography polygon?
Here's what I came up with:
DECLARE #g GEOGRAPHY = /* your hex representation from above */
#new VARCHAR(MAX);
WITH points AS (
SELECT #g.STPointN(n.n) AS p, n
FROM tempdb.dbo.Numbers AS n
WHERE n <= #g.STNumPoints()
)
SELECT #new = CONCAT('POLYGON((', (
SELECT STRING_AGG(CONCAT(p.Lat, ' ', p.Long), ',') WITHIN GROUP (ORDER BY p.n)
FROM points AS p
), '))')
SELECT geography::STGeomFromText(#new, #g.STSrid).ReorientObject();
It's pretty straightforward. I'm creating a common table expression (CTE) to decompose the existing polygon into its constituent corners using a numbers (or tally) table. All that is is a table with one column with integers from 1 to some large number. It's helpful for cases like this. From there, I'm swapping the latitude and longitude of the points and then re-assembling them into the WKT for the polygon. Lastly, I'm creating an actual geography instance from the WKT. Note - I'm calling ReorientObject() as the new polygon appears to suffer from a ring orientation problem insofar as it defined the whole globe with a small hole in it (the shape of your polygon).

How to get the distance between points in my geom and entry point longitude and latitude

everyone, I have table name 'geom' and I would like to calculate the distance between points that exist in my table like 0101000020730800001DAB949EE95D4040E124CD1FD3F04340
and entry points longitude and latitude and I tried this
SELECT *
FROM postgis.cafeecoor
WHERE ST_Distance_Sphere(geom, ST_MakePoint(32.733792,39.865589)) <= 1 * 1609.34
You can use the geography datatype that returns distances in meters.
SELECT *, st_distance(geom::geography, ST_MakePoint(32.733792,39.865589)::geography)
FROM postgis.cafeecoor
For your example, it returns 1760.32533367 meters.
Depending how your geometry is saved (as a true geometry or as text, with or without a set projection), you might have to add a few extra steps, like creating the geometry and setting its coordinate system
SELECT *, st_distance(
st_setsrid(geom::geometry,4326)::geography,
ST_MakePoint(32.733792,39.865589)::geography)
FROM postgis.cafeecoor;

linestring created from coordinates POSTGIS

Can someone help ?
Here is the part of my code (sql) which doesn't work :
SELECT ST_LENGTH(geom) into distance FROM
SELECT ST_GeographyFromText('srid=4326;linestring(lon_bus lat_bus, lon_stop lat_stop)') AS geom)
AS dis;
lon_bus, lat_bus, lon_stop and lat_stop are coordinates I get from my database. When I try this, I have an error of parsing. But when I replace these variable by numeric, it works. Can someone help me on it? I would like to keep these variables in my code.
It doesn't work because the WKT with variables is invalid. Remember, WKT is just regular text, so don't confuse WKT with SQL.
You can make a LineString from two point geometries, then cast it to ::geography.
SELECT ST_MakeLine(ST_MakePoint(lon_bus, lat_bus),
ST_MakePoint(lon_stop, lat_stop))::geography AS geog
FROM (
SELECT 1 AS lon_bus, 2 AS lat_bus, 3 AS lon_stop, 4 AS lat_stop
) AS data;
To get the geodesic length, use ST_Length on the geography.
Based on the usage, the question isn't about how to make a linestring, but how to calculated the distance between two geographic positions. There are several ways to do this:
SELECT
ST_Distance(bus, stop) AS cartesian_distance,
ST_Distance_Sphere(bus, stop) AS sphere_distance,
ST_Distance(bus::geography, stop::geography) AS geography_distance,
ST_Length(ST_MakeLine(bus, stop)::geography) AS geography_length
FROM (
SELECT ST_MakePoint(lon_bus, lat_bus) AS bus, ST_MakePoint(lon_stop, lat_stop) AS stop
FROM (SELECT 1 AS lon_bus, 2 AS lat_bus, 3 AS lon_stop, 4 AS lat_stop) AS data
) AS data;
-[ RECORD 1 ]------+-----------------
cartesian_distance | 2.82842712474619
sphere_distance | 314283.687770102
geography_distance | 313588.397192902
geography_length | 313588.397192902
The last two get the same result. If you don't need the linestring (e.g. to draw on a map), then the simplest method is used for geography_distance.

Can't get a simple Entity Framework spatial query to work

This query on my sql server returns lots of rows:
declare #referencepoint Geography = Geography::Point(48.208173, 16.373813, 4326);
SELECT *
FROM myTable
WHERE Location.STDistance(#referencepoint) < 20000
but the equivalent in EF returns none:
DbGeography referencepoint = DbGeography.PointFromText("POINT(48.208173 16.373813)", 4326);
var records = (from r in db.myTable
where r.Location.Distance(referencepoint ) <= 20000
select r).ToList();
Looking at the query generated via profiler I see this:
declare #p3 sys.geography
set #p3=convert(sys.geography,0xE6100000010CD4D17135B25F30408274B169A51A4840)
SELECT *
FROM [myTable]
WHERE ([Location].STDistance(#p3)) <= 20000
Does EF have an issue here, or do I?
OP has the issue here :) Both SQL and EF are working as expected. OP's statement was incorrect.
SQL Point Syntax:
declare #referencepoint Geography = Geography::Point(48.208173, 16.373813, 4326);
is actually equivalent to .Net:
DbGeography referencepoint = DbGeography.PointFromText("POINT(16.373813 48.208173)", 4326);
// Note the parameters are reversed from OP's statement
In SQL and EF (.Net) the Geography data type uses a standard WellKnownText notation to define points and polygons and other structures internally.
In WellKnownText format a Point is specified as POINT(X Y) on a Cartesian plane.
- Note the lack of a comma, the values are only delimited by a space
When we want to express the location on the earth as a point on a Cartesian plane, the X axis is the equator, the Y axis is then a Meridian line running between the North and South Poles.
Longitute, by definition is the east-west position on the surface of the Earth (so parallel with the equator, the X ordinate)
Latitude, by definition is the north-south position on the surface of the Earth (perpendicular to the equator, the Y ordinate)
Therefore to express a Point on the earth in WellKnownText format as if it were a point on a Cartesian plane we must use this syntax:
POINT(Longitude Latitude)
What confuses the issue is that in most verbal and written forms we refer to Latitude and Longitude in that order, so in SQL we have a helper function that takes the parameters in that order, because this was supposed to make it less confusing. And in a way it is, because the parameters are named appropriately. To further explain the point I have expanded out OP's statements with the correction
SQL
DECLARE #latitude float = 48.208173
DECLARE #longitude float = 16.373813
DECLARE #srid int = 4326
DECLARE #referencepoint Geography = Geography::Point(#latitude, #longitude, #srid);
SELECT *
FROM myTable
WHERE Location.STDistance(#referencepoint) < 20000
.Net
double latitude = 48.208173;
double longitude = 16.373813;
int srid = 4326;
DbGeography referencepoint = DbGeography.PointFromText($"POINT({longitude} {latitude})", srid);
var records = (from r in db.myTable
where r.Location.Distance(referencepoint) <= 20000
select r).ToList();
I can't even find a good reference explaining why we generally refer to Latitude and Longitude (in that order) I suspect it's based on the fact that LatLon rolls off the tongue better or because latitude was discovered/measured first?

How do I use the great circle distance calculation in T-SQL

How can i control the latitude and the longitude of the Team and the Customer with reasonable error margin from the Job Table?
if the two values are close to eachother i will return it "true", if not "false"
Job Table (like this) :
JobID CustomerID TeamID
2 13 1
3 13 2
Team Table :
TeamID Latitude Longitude
1 41.019 28.965
2 42.019 27.165
Customer Table
ID Latitude Longitude
13 13.557 13.667
The function:
CREATE FUNCTION dbo.DictanceKM(#lat1 FLOAT, #lat2 FLOAT, #lon1 FLOAT, #lon2 FLOAT)
RETURNS FLOAT
AS
BEGIN
RETURN ACOS(SIN(PI()*#lat1/180.0)*SIN(PI()*#lat2/180.0)+COS(PI()*#lat1/180.0)*COS(PI()*#lat2/180.0)*COS(PI()*#lon2/180.0-PI()*#lon1/180.0))*6371
END
i assume you mean: how can i write a select statement to return true if two latitudes and longitudes are within x miles of each other... or something like that?
look up 'great_circle_distance'
write a query that links the customer to the team.
perform the great circle distance calculation on the two lats and longs.
compare this to you desired distance.
use decode or some similar construct to turn that into a 'True' or 'False' value.
SQL has a geography datatype and a method to calculate the distance between two. Covert your Lat, Long pairs to geography.
http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.types.sqlgeography.stdistance.aspx
Then you could use a function to return a true or false.

Resources