Oracle Spatial transform - oracle-spatial

We have a table in an Oracle Spatial database containing polygons (lying in Austria) in Lambert projection (SRID=1000047), which we want to transform into WGS84 (SRID=8307). After performing
create table Table2 as (
select ..., SDO_CS.TRANSFORM(geometry, 8307) as geometry, ...
from Table1)
the polygons in Table2 all lie practically on a single point north of Paris. What are we doing wrong?
Edit: As an example, the point [11.26555560027597,53.87928275206266] gets transformed to [2.3069645331040123,49.293822884973984]. I get the same results using SRID=4326 instead of 8307.
The sqlplus query select * from cs_srs where srid=100047 returns
PROJCS["LAMBERT",GEOGCS["GCS_MGI",DATUM["D_MGI",SPHEROID["Bessel_1841",6377397.1‌55,299.1528128]], PRIMEM["Greenwich",0],UNIT["Decimal Degree",0.017453292519943295]],PROJECTION["Lambert Conformal Conic"], PARAMETER["False_Easting",400000],PARAMETER["False_Northing",400000], PARAMETER["Central_Meridian",13.33333333333333],PARAMETER["Standard_Parallel_1",‌​46], PARAMETER["Standard_Parallel_2",49],PARAMETER["Scale_Factor",1], PARAMETER["Latitude_Of_Origin",47.5],UNIT["Meter",1]]

Your source SRID (1000047) is not a standard EPSG code, neither is it any coordinate system that ships with any version of Oracle: it looks like one you defined yourself. Can you show us the definition (select * from cs_srs where srid=1000047) ?
Looking at your input (11.26555560027597,53.87928275206266) - that does not look like any projection. It looks to me like some geodetic coordinates, possibly on a different datum than WGS84.
The coordinate system definition you use is that of the standard SRID 31287:
PROJCS[
"MGI / Austria Lambert",
GEOGCS["MGI",
DATUM["Militar-Geographische Institut",
SPHEROID[
"Bessel 1841",
6377397.155,
299.1528128,
AUTHORITY["EPSG", "7004"]],
TOWGS84[577.326, 90.129, 463.919, 5.137, 1.474, 5.297, 2.4232],
AUTHORITY["EPSG", "6312"]],
PRIMEM["Greenwich", 0.000000, AUTHORITY["EPSG","8901"]],
UNIT["degree (supplier to define representation)", 0.0174532925199433, AUTHORITY["EPSG", "9122"]],
AXIS["Lat", NORTH],
AXIS["Long", EAST],
AUTHORITY["EPSG", "4312"]],
PROJECTION ["Lambert Conformal Conic"],
PARAMETER ["Latitude_Of_Origin", 47.5],
PARAMETER ["Central_Meridian", 13.3333333333333333],
PARAMETER ["Standard_Parallel_1", 49.0],
PARAMETER ["Standard_Parallel_2", 46.0],
PARAMETER ["False_Easting", 400000.0],
PARAMETER ["False_Northing", 400000.0],
UNIT["metre", 1.0, AUTHORITY["EPSG", "9001"]],
AXIS["X", NORTH],
AXIS["Y", EAST],
AUTHORITY["EPSG", "31287"]]
The main difference with yours is that yours is missing the datum shift parameters. The other difference is that the standard parallels are reversed: parallel 1 is 49 and parallel 2 is 46 vs. 46 and 49 in your definition.
Here is what I get when I transform the geometry you posted as example (encoded using 31287):
select sdo_cs.transform (
sdo_geometry(2003,31287,null,sdo_elem_info_array(1, 1003, 1),sdo_ordinate_array(607205.274999979, 528729.87700098, 607052.849999979, 528254.154000983, 607080.702999979, 528224.753000982, 607098.889999979, 528220.193000982, 607113.807999979, 528225.393000979, 607272.533999979, 528720.85100098, 607269.772999979, 528724.96700098, 607205.274999979, 528729.87700098)),
4326
)
from dual;
SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(16.1442004, 48.62389, 16.1419009, 48.6196637, 16.1422641, 48.6193904, 16.1425084, 48.6193435, 16.1427132, 48.6193854, 16.1451079, 48.623787, 16.1450725, 48.6238249, 16.1442004, 48.62389))
The result looks fine to me. Can you verify that it is ?
What exact version of Oracle do you run? SRID 31287 exists since 10gR2.
The simplest seems to me to use srid 31287 for your data instead of the custom 100047.

Related

ST_Area does not exist Heroku Postgresql + Postgis

I have a Postgres extended with Postgis version 2.5 database in Heroku.
I want to use the function:
ST_Area( a_polygon )
Specifically I want a generated column in my table:
alter table buildings add building_area float generated always as ( st_area( base_polygon ) ) stored;
Where base_polygon is of type polygon.
However, I am getting this error:
ERROR: function st_area(polygon) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Aren't these commands supposed to be available after I run CREATE EXTENSION postgis?
Or, is there something else I have to do?
It seems your polygon column data type is postgre base built in polygon.
ST_Area expects postgis geometry type as a parameter.
As in this example from docs https://postgis.net/docs/ST_Area.html
select ST_Area(geom) sqft,
ST_Area(ST_Transform(geom, 26986)) As sqm
from (
select
'SRID=2249;POLYGON((743238 2967416,743238 2967450,
743265 2967450,743265.625 2967416,743238 2967416))' :: geometry
geom
) subquery;
Check if this example works, it means that ST_Area function exists.
You can add a column with postgis geometry type. https://postgis.net/docs/AddGeometryColumn.html
SELECT AddGeometryColumn ('my_schema','my_spatial_table','geom',4326,'POLYGON',2);
Then convert your polygons into postgis format, by postgis functions.
For example https://postgis.net/docs/ST_MakePolygon.html
SELECT ST_MakePolygon( ST_GeomFromText('LINESTRING(75 29,77 29,77 29, 75 29)'));

Given a point, how can I query SQL Server to find the stored polygons that encompass it?

Given a point, how can I query SQL Server to find the stored polygons that encompass it?
I have a database table that has the polygons of all 50 US states. I need a query that will allow me to search for which states are within 90 miles of that point.
Here is my table structure and data for three states:
CREATE TABLE dbo.States (
State varchar(20) NOT NULL,
CoordinatorEmail varchar(255) NULL,
Borders geography(-1) NULL
);
INSERT INTO States (State, Borders)
VALUES ('Alaska', (geography::STGeomFromText('POLYGON((-141.0205 70.0187,-141.7291 70.1292,-144.8163 70.4515,-148.4583 70.7471,-151.1609 70.7923,-152.6221 71.1470,-153.9954 71.1185,-154.8853 71.4307,-156.7529 71.5232,-157.9449 71.2796,-159.6313 71.2249,-161.8671 70.6363,-163.5809 70.0843,-165.2399 69.3028,-166.8768 69.1782,-168.0414 68.3344,-165.9155 67.6844,-164.6082 67.2933,-164.0149 66.7789,-165.7507 66.5810,-167.5745 66.2867,-168.9862 66.0269,-168.9478 65.4970,-167.4756 65.0420,-167.0142 64.3922,-165.7343 64.0554,-163.2294 64.0193,-162.1143 63.9615,-163.6029 63.6877,-165.3717 63.4530,-166.3715 62.4133,-166.9867 61.6534,-166.4429 60.8556,-167.8381 60.5357,-167.7118 59.5482,-165.8002 59.4115,-164.5972 59.3696,-162.8558 59.1168,-162.5427 58.1185,-160.6421 58.1359,-159.5050 58.0285,-158.8953 57.6336,-159.9060 56.9090,-160.6531 56.3926,-161.8835 56.2342,-162.9822 55.7240,-164.3994 55.2478,-165.3168 54.7753,-167.1075 54.1463,-168.5852 53.5632,-169.9146 53.1402,-169.5959 52.5964,-168.2227 52.9089,-162.7734 54.2139,-159.1452 54.6786,-155.4634 55.6567,-152.1400 57.3510,-150.8203 59.2209,-147.4461 59.7695,-145.9850 60.3521,-144.1544 59.8917,-141.6811 59.8172,-140.5124 59.5225,-138.8548 59.0292,-136.8526 57.9032,-136.0725 56.9157,-134.9794 56.1555,-134.0057 55.3237,-133.6418 54.6341,-130.6261 54.7135,-129.9930 55.2869,-130.0108 55.9869,-130.1083 56.1057,-131.5887 56.6086,-132.8755 57.8404,-133.8423 58.7276,-134.9121 59.3108,-135.4724 59.8020,-136.3445 59.6039,-136.8251 59.1619,-137.6079 59.2441,-139.2119 60.0902,-139.0938 60.3575,-140.0056 60.1866,-140.9999 60.3059,-141.0205 70.0187,-141.0205 70.0187))', 4326)));
INSERT INTO States (State, Borders)
VALUES ('Alabama', (geography::STGeomFromText('POLYGON((-88.1955 35.0041,-85.6068 34.9918,-85.1756 32.8404,-84.8927 32.2593,-85.0342 32.1535,-85.1358 31.7947,-85.0438 31.5200,-85.0836 31.3384,-85.1070 31.2093,-84.9944 31.0023,-87.6009 30.9953,-87.5926 30.9423,-87.6256 30.8539,-87.4072 30.6745,-87.3688 30.4404,-87.5240 30.1463,-88.3864 30.1546,-88.4743 31.8939,-88.1021 34.8938,-88.1721 34.9479,-88.1461 34.9107,-88.1955 35.0041))', 4326)));
INSERT INTO States (State, Borders)
VALUES ('Arkansas', (geography::STGeomFromText('POLYGON((-94.0416 33.0225,-91.2057 33.0075,-91.1989 33.1180,-91.1041 33.1824,-91.1343 33.3053,-91.1646 33.4211,-91.2263 33.4337,-91.2524 33.5403,-91.1797 33.6112,-91.2524 33.6855,-91.1261 33.6946,-91.1412 33.7883,-91.0451 33.7700,-91.0341 33.8328,-91.0863 33.9399,-90.9256 34.0208,-90.9036 34.0856,-90.9586 34.1345,-90.9132 34.1675,-90.8501 34.1380,-90.9325 34.2311,-90.6935 34.3446,-90.5603 34.4409,-90.5548 34.5348,-90.5768 34.5959,-90.5301 34.7213,-90.5328 34.7574,-90.4546 34.8780,-90.3529 34.8454,-90.2911 34.8690,-90.3104 35.0255,-90.2843 35.1154,-90.1772 35.1323,-90.1112 35.1985,-90.1524 35.2826,-90.1332 35.4383,-90.0206 35.5579,-89.9780 35.6740,-89.9547 35.7287,-89.6594 35.9169,-89.6883 35.9658,-89.7130 36.0013,-90.3735 35.9958,-90.2664 36.1268,-90.0934 36.2875,-90.0742 36.3892,-90.1511 36.4180,-90.1566 36.4997,-94.6198 36.4986,-94.4412 35.3801,-94.4893 33.6318,-94.4522 33.6421,-94.4000 33.5597,-94.2462 33.5883,-94.1885 33.5872,-94.0375 33.5345,-94.0430 33.4314,-94.0430 33.0213,-94.0416 33.0225))', 4326)));
I have been trying the following query just to make sure I can get the state of the point (without yet worrying about the 90 mile radius), but I haven't figure this part out yet.
DECLARE #LittleRock geography;
SET #LittleRock = geography::Point(34.742000, -92.276543, 4326);
Select State from States
where States.Borders.STIntersects(#LittleRock) = 1;
SELECT State from States
where States.Borders.STContains(#LittleRock) = 1;
Neither STIntersets() nor STContains() returns anything. Thoughts?
When I ran your code on my local instance, I got the following error (abbreviated):
This operation cannot be completed because the instance is not valid.
Use MakeValid to convert the instance to a valid instance.
Next, I did what the robot told me to do:
UPDATE dbo.States
SET Borders = Borders.MakeValid();
Once that was done, I was able to determine that Little Rock is indeed in Arkansas with both STIntersects() and STContains(). So there was something malformed in at least one of your geography instances.
EDIT
Given the OPs full data set, it has another issue with some of the states. Specifically, 21 states appear to have a ring orientation problem. With Geography polygons, the order in which you specify the vertexes is important. I never remember whether clockwise or counter-clockwise is the right direction. But I do remember the heuristic I use. If the envelope angle for the polygon is greater than 90°, I probably got it wrong. Luckily, that is also easy to correct for.
UPDATE s
SET s.Borders = s.Borders.ReorientObject()
FROM dbo.States AS s
WHERE s.Borders.EnvelopeAngle() > 90
With the raw data set, your Little Rock query returns 22 states. With the update above run, it returns only Arkansas.

How to convert from PostgreSQL to GeoJSON format?

I have a simple table called"imposm3_restaurant" with columns [ id, name, geometry] I want to convert these data into geoJSON, I am using this function
CREATE VIEW imposm3_restaurants_geojson AS SELECT row_to_json(fc) AS geojson FROM
(SELECT 'FeatureCollection' As type, array_to_json(array_agg(f))
As features FROM
(SELECT
'Feature' As type,
ST_AsGeoJSON((lg.geometry),15,0)::json As geometry,
row_to_json((id, name)) As properties
FROM imposm3_restaurants As lg) As f ) As fc;
and the result is this:
{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"LineString","coordinates":[[2615020.47191046,5899232.25158985],[2615034.50527113,5899231.67978097],[2615033.86145338,5899215.4513157],[2615032.35921198,5899215.51938806],[2615031.96732292,5899205.64890158],[2615034.97180572,5899205.51275702],[2615034.36531075,5899190.07397728],[2615018.19522163,5899190.71385561],[2615018.77372453,5899205.40384137],[2615020.47191046,5899205.32215463],[2615020.91045298,5899216.48601561],[2615019.83742341,5899216.52685903],[2615020.47191046,5899232.25158985]]},"properties":{"f1":2719,"f2":"Atelierul de Pizza"}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[2615018.19522163,5899190.71385561],[2615018.77372453,5899205.40384137],[2615020.47191046,5899205.32215463],[2615020.91045298,5899216.48601561],[2615019.83742341,5899216.52685903],[2615020.47191046,5899232.25158985],[2615034.50527113,5899231.67978097],[2615033.86145338,5899215.4513157],[2615032.35921198,5899215.51938806],[2615031.96732292,5899205.64890158],[2615034.97180572,5899205.51275702],[2615034.36531075,5899190.07397728],[2615018.19522163,5899190.71385561]]]},"properties":{"f1":2720,"f2":"Atelierul de Pizza"}},{"type":"Feature","geometry":{"type":"LineString","coordinates":[[2624875.82864931,5903443.39761349],[2624897.49451598,5903452.78251964],[2624901.44139867,5903443.67003443],[2624879.78486269,5903434.29875908],[2624875.82864931,5903443.39761349]]},"properties":{"f1":2986,"f2":"Pizza Acrobatica"}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[2624875.82864931,5903443.39761349],[2624897.49451598,5903452.78251964],[2624901.44139867,5903443.67003443],[2624879.78486269,5903434.29875908],[2624875.82864931,5903443.39761349]]]},"properties":{"f1":2988,"f2":"Pizza Acrobatica"}},{"type":"Feature","geometry":{"type":"LineString","coordinates":[[2622460.22447654,5904586.41424973],[2622479.10046632,5904587.95362911],[2622480.25747212,5904573.81314552],[2622461.39081303,5904572.26014582],[2622460.22447654,5904586.41424973]]},"properties":{"f1":3248,"f2":"Casa Vikingilor"}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[2622460.22447654,5904586.41424973],[2622479.10046632,5904587.95362911],[2622480.25747212,5904573.81314552],[2622461.39081303,5904572.26014582],[2622460.22447654,5904586.41424973]]]},"properties":{"f1":3249,"f2":"Casa Vikingilor"}},{"type":"Feature","geometry":{"type":"LineString","coordinates":[[2625201.09657005,5897608.45120294],[2625224.46062264,5897614.30435379],[2625241.33051365,5897576.653689],[2625213.43174478,5897570.82778714],[2625201.09657005,5897608.45120294]]},"properties":{"f1":6152,"f2":"Silva"}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[2625201.09657005,5897608.45120294],[2625224.46062264,5897614.30435379],[2625241.33051365,5897576.653689],[2625213.43174478,5897570.82778714],[2625201.09657005,5897608.45120294]]]},"properties":{"f1":6153,"f2":"Silva"}},{"type":"Feature","geometry":{"type":"LineString","coordinates":[[2622825.25980629,5904372.27967993],[2622826.15555271,5904353.45341631],[2622834.51585268,5904353.1673446],[2622854.22227404,5904346.00193242],[2622860.03529512,5904362.26715407],[2622856.61093118,5904374.66361634],[2622825.25980629,5904372.27967993]]},"properties":{"f1":6322,"f2":"Restaurant Sinaia"}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[2622825.25980629,5904372.27967993],[2622856.61093118,5904374.66361634],[2622860.03529512,5904362.26715407],[2622854.22227404,5904346.00193242],[2622834.51585268,5904353.1673446],[2622826.15555271,5904353.45341631],[2622825.25980629,5904372.27967993]]]},"properties":{"f1":6323,"f2":"Restaurant Sinaia"}}]}
which does not have a current geometry, do you know what is wrong in function: I am using Postgres 9.3 and PostGIS 2.2
Your output is a valid geojson file but the geometries are projected using the projection EPSG:3857.
You can load the data without problems in the most gis desktop applications, in example Quantum Gis.
Probably geojson.io supports only long/lat coordinates EPSG:4326, also try reprojecting the geometries to long/lat coordinates using the function St_Transform
Change this line:
ST_AsGeoJSON((lg.geometry),15,0)::json As geometry,
in this:
ST_AsGeoJSON(ST_Transform(lg.geometry, 4326),15,0)::json As geometry,

How to calculate area in SQL using geographic coordinates?

Does anybody know what is the problem with my query. I am trying to calculate area using geographical coordinates, but result seems to be too small to be true. 0.00118 sqm. Can anybody help?
SELECT ST_Area(the_geom) As sqm
FROM (SELECT
ST_GeomFromText('POLYGON
(
(14.604514925547997 121.0968017578125,
14.595212295624522 121.08512878417969,
14.567302046916149 121.124267578125,
14.596541266841905 121.14761352539062,
14.604514925547997 121.0968017578125)
)',4326) ) As foo(the_geom)
How accurate should be the calculation?
A solution is to cast GEOMETRY to GEOGRAPHY, which is acceptably accurate for the most use cases:
SELECT ST_Area(the_geom::GEOGRAPHY ) As sqm
FROM (SELECT
ST_GeomFromText('POLYGON
(
(14.604514925547997 121.0968017578125,
14.595212295624522 121.08512878417969,
14.567302046916149 121.124267578125,
14.596541266841905 121.14761352539062,
14.604514925547997 121.0968017578125)
)',4326) ) As foo(the_geom)
The geography type automatically converts degrees to meters.
Depending on your scenario you could also use directly the geography constructor St_GeographyFromText, which accept a WKT string as argument, very similar to ST_GeomFromText
ST_GeographyFromText('POLYGON((14.604514925547997 121.0968017578125,
14.595212295624522 121.08512878417969,
14.567302046916149 121.124267578125,
14.596541266841905 121.14761352539062,
14.604514925547997 121.0968017578125))'
)

Querying Netezza via SquirrelSQL returns WKT geometry in unknown encoding

I am using SquirrelSQL to write and execute SQL queries on a Netezza database. Using Netezza's spatial capabilities (which are essentially the same as those of PostGIS) I've executed a query and returned a single result that contains a geometry. Here's the query, for reference:
SELECT t.SHAPE
FROM (SELECT * FROM OS_AB_PLUS..E12_ADDRESSBASE WHERE POSTCODE = 'RH1 6NE'
AND PAO_START_NUMBER = '14') as a, OS_TOPO..TOPOGRAPHICAREA as t
WHERE inza..ST_Within(a.shape, t.shape) = TRUE
My issue is that the geometry field, which should contain the polygon coordinates represented as Well-Known Text (WKT), looks instead like this:
g¹ AË Affff¬0AÍÌÌÌî0AÒ 3333Ê AÍÌÌÌî0A» Aë0Afffæ» AffffÒ0A¹ AÒ0A333³¹ A3333¿0AŒ AffffÀ0AÍÌÌLŒ Affff¬0AË A¯0AëQ8Ê A3333í0A3333Ê AÍÌÌÌî0A
I can't seem to find anywhere in SquirrelSQL to specify the encoding of VARCHAR columns, and I've seen the column returned without encoding issues in Aginity (another SQL client). Any suggestions on how to proceed would be much appreciated.
Turns out my issue was not really related to encoding at all. The human-readable version of the geometry in a PostGIS-like database will only be returned when ST_AsText is used in the select statement. So my SQL query becomes:
SELECT inza..ST_AsText(t.SHAPE)
FROM (SELECT * FROM OS_AB_PLUS..E12_ADDRESSBASE WHERE POSTCODE = 'RH1 6NE'
AND PAO_START_NUMBER = '14') as a, OS_TOPO..TOPOGRAPHICAREA as t
WHERE inza..ST_Within(a.shape, t.shape) = TRUE
Which returns. as intended:
POLYGON ((526696.15 148931.9, 526703.94 148932.34, 526703.8 148935.2, 526705.5 148935.3, 526705.4 148937.8, 526695.9 148937.35, 526696.15 148931.9))