PostGIS point attributes to polygons, where poligon contain point - postgis

I have a polygon database (bdus) and a point database (bdps) under the same schema in PostGIS. These databases were imported from shapefiles with the Shapefile and DBF loader. What I want to do is to join the point attributes on the polygon layer based on the contain criteria.
So for every polygon that contain one to n points, to add the columns of points to polygons. If there are more than one point a good approach would be to average column values.
Can someone guide me? I am new to PostGreSQL and PostGIS but I managed to run this query
SELECT * FROM bdps
JOIN
bdus
ON
ST_Contains(bdus.the_geom, bdps.the_geom);
which return a table with bdps joined with the corresponding bdus, but I want the reverse.
Thanks in advance for any help!

Did you meant, that you want to create a new polygon with the polygon and the points that satisfy the ST_Contains(polys, points) criteria?
SELECT ST_Union(bdus.the_geom, bdps.the_geom) FROM bdus,bdps WHERE
ST_Contains(bdus.the_geom, bdps.the_geom);

Related

How to calculate distance in "km" using a points geometry column to the nearest linestring geometry column in SQL Server spatial

I am looking to create a field that tells me the nearest neighbour distance in km between 2 geometric columns.
I have a point dataset and multiline dataset both with the geometric fields.
I tried the following:
SELECT
p.GEOM.STDistance(l.GEOM) AS distance
FROM
[points] p, [dbo].[lines] l
after running this query I get the following message
Msg 6522, Level 16, State 1, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "geometry":
System.ArgumentException: 24144: This operation cannot be completed because the instance is not valid. Use MakeValid to convert the instance to a valid instance. Note that MakeValid may cause the points of a geometry instance to shift slightly.
System.ArgumentException:
Could you help me with this one please?
Much appreciated!
Thanks!
The error seems to indicate you have bad spatial data in one of the tables but the query you're using has issues as well. Run this
select ID, geom.STisValid() from lines
and
SELECT ID, geom.STisValid() from points
To see if you have any bad geometry records. If you do run
update table 'with bad spatial datatype'
set geom = geom.MakeValid()
Once you're sure the spatial data is valid rework your query to use a cross join (compare every line to every point (and get the distance) and store the results in a temp table.
Query the temp table for the min(distance) for each point or line. Provided you only need to know the closest feature and not a distance you can do all this with geometry data. If you need to have a measure in feet or meters you will need to convert your data from geometry to geography.
If you have a large number of features in either table the cross join could take forever. Try to work it out on a subset.

Remove Geometry data that is outside of a polygon

I am creating a SQL Server table that takes data from a OS MasterMap layer if it sits within the SITES_TEST layer.
First I am using STIntersects to get the OS MM data into an ASSETS layer.
INSERT INTO ASSETS(GEOMETRY, THEMES)
(select b.GEOMETRY, b.THEMES from
SITES_TEST a,
MM_TOPO b
where a.geometry.STBuffer(1).STIntersects(b.geometry) = 1 AND (b.THEMES ='Land' or b.THEMES ='Roads Tracks And Paths'))
The Blue boundary is my site layer and in the background OS MasterMap.
After the query above is run in SQL Server it returns the overlapping data as well as the contained data. I get that I could use STContains but then that leaves out data that goes both within and outside the boundary.
I was hoping I would be able to run an UPDATE on the ASSETS table using STDifference.
UPDATE ASSETS(GEOMETRY)
(select b.GEOMETRY from
SITES_TEST a,
MM_TOPO b
where a.geometry.STDifference(b.geometry)=1)
But I think I am going about it the wrong way as this is returning a boolean error.
Invalid operator for data type. Operator equals equal to, type equals
geometry.
Summary:
I am trying to remove geometry that is outside of another geometry. The first picture shows a blue polygon, then the SQL script is run which results in the second picture which shows data in red that sits outside the blue boundary polygon from the first picture. I want to remove the data that is now outside the blue polygon.
Instead of just asking for geometries that intersect the polygon of interest, which returns all of the intersecting geometry (as you found out) you want just the parts of the geometry that intersect your polygon of interest. So something like:
INSERT INTO ASSETS(GEOMETRY, THEMES)
(select b.GEOMETRY.STIntersection(a.geometry, b.THEMES from
SITES_TEST a,
MM_TOPO b
where a.geometry.STBuffer(1).STIntersects(b.geometry) = 1 AND (b.THEMES ='Land' or b.THEMES ='Roads Tracks And Paths'))

How to use superset's mapbox view when longitude and latitude are in postgis point format?

I am trying to make an apache superset chart with map box view.
I have to set latitude and longitude columns. But these data are in a postgresql + postgis database. So, latitude and longitude are in the same column location. An sql query would be like this:
SELECT ST_X(location), ST_Y(location) FROM Address
How can I make superset get latitude with the function ST_X()?
Mapbox also supports other geometry flavours, such as WKT (Well Known Text) and GeoJSON, so it is normally not necessary to split them in X,Y or Y,X pairs.
To retrieve GeoJSON from PostgreSQL (+PostGIS):
SELECT ST_AsGeoJSON(location) FROM t;
And as WKT:
SELECT ST_AsText(location) FROM t;
Superset makes it possible to create "virtual" columns in tables.So I created columns latitude with this expression:
ST_X(location)
And that worked
thanks to this superset team:
https://github.com/apache/incubator-superset/issues/4640#event-1527353388

Merging SQL Spatial polygons where there is a calculated column

I'm having trouble getting polygons in a SQL Spatial table to merge where there is a calculated column.
The original query works great:
SELECT RollNumber, Geometry, geometry::UnionAggregate(Geometry_SPA.MakeValid()) AS Geometry_SPA
FROM dbo.LegalParcel
GROUP BY RollNumber, Geometry
It returns a set of polygons merged by their tax roll numbers.
However we want to know areas, so we added a computed column:
SELECT RollNumber, Geometry_SPA.STArea() AS SqMetres, Geometry, geometry::UnionAggregate(Geometry_SPA.MakeValid()) AS Geometry_SPA
FROM dbo.LegalParcel
GROUP BY RollNumber, Geometry, Geometry_SPA.STArea()
Since this required adding Geometry_SPA to the Group By, now the polygons which are supposed to merge come back as discrete records.
I attempted to add the aggregation onto the new SqMetres column
columngeometry::UnionAggregate(Geometry_SPA.STArea()) As SqMetres
However that ends with the error ‘Operand type clash: float is incompatible with geometry’
How can I get the necessary records to merge?
Note for anyone wondering why there are two Geometry columns: It is a requirement of our GIS software.
Apparently the issue traced back to some questionable polygons in the source table. After running
update dbo.legalparcel set Geometry_SPA=Geometry_SPA.MakeValid()
where Geometry_SPA.STIsValid() = 0
I'm now getting correct results using the original computed column.

How to make a polygon with a hole

I'm using postgresSQL with postgis and I'm trying to create a polygon with a hole. I read a lot of users asking for something similar, but I can't do it for myself. My code is
insert into distritos(nombre,geom) values ('Distrito6',ST_MakePolygon(ST_GeomFromText('LINESTRING((-15.66486 27.91996, -15.60610 27.91820, -15.60359 27.97169, -15.66586 27.97144,-15.66486 27.91996),(-15.65753 27.95894, -15.61610 27.95995, -15.61459 27.93157, -15.65477 27.27.93007,-15.65753 27.95894))',4258)));
but it doesn't work. What do I have to do?
A Polygon has a double parenthesis at the start and end, and inner rings are delineated by using single pairs of parenthesis, between commas, ie, ),( whereas a Linestring only has one set of parenthesis at the beginning and end. You are actually using the syntax for a MultiLinestring, which is probably where your issue is. You can fix you query like this:
insert into distritos(nombre, geom) values
('Distrito6', ST_GeomFromText('POLYGON((-15.66486 27.91996,
-15.60610 27.91820, -15.60359 27.97169, -15.66586 27.97144,-15.66486 27.91996),
(-15.65753 27.95894, -15.61610 27.95995, -15.61459 27.93157,
-15.65477 27.93007,-15.65753 27.95894))',4258));
Also, you do not need to use ST_MakePolygon, as if you are using ST_GeomFromText, you can create the polygon directly by using POLYGON instead of LINESTRING in your example above. ST_MakePolygon is probably more useful when you have arrays of Linestrings representing inner rings.
The Wikipedia WKT article details this very clearly, with WKT and accompanying graphics.
NOTE: You also have an error in you linestring, you have a repeated 27. in 27.27.93007.

Resources