Merging SQL Spatial polygons where there is a calculated column - sql-server

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.

Related

Calculated field over list of values

Given this table of data:
I'd like to produce this pivot table:
I have an inkling this can be done with the calculated field, and SUMIF, but am not able to get it to work. I think the main blocker is that I'm not able to find good documentation for what I can reference inside of a calculated field formula. My best attempt was =SUMIF(color, "RED")/SUM(), but that produced zeros.
Example table at https://docs.google.com/spreadsheets/d/16htOLbwf47Neo68iFlm9OvFVS_u2Jlc-2thhdUQwrpU/edit?usp=sharing
Any guidance appreciated!
={QUERY(A1:B25,"select A,count(A)/"&COUNT(A:A)&" where B='RED' group by A label count(A)/"&COUNT(A:A)&" 'PCT RED'");{"Grand Total",COUNTIFS(A:A,">=0",B:B,"RED")/COUNT(A:A)}}
Function References
Query
COUNT
COUNTIFS
I think my concern here would be that with a normal pivot table it's robust against data moving around. This seems to break that by referencing specific columns
Method pivot table you must show all color
I think my concern here would be that with a normal pivot table it's robust against data moving around. This seems to break that by referencing specific columns
to "set it free" you can do:
={QUERY({A:B},
"select Col1,count(Col1)/"&COUNT(A:A)&"
where Col2='RED'
group by Col1
label count(Col1)/"&COUNT(A:A)&"'PCT RED'");
{"Grand Total", COUNTIFS(A:A, ">=0", B:B, "RED")/COUNT(A:A)}}

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'))

Find rows with exact geography coordinates

I have a SQL table with a geography column. When I look at one of the rows the geography shows as a long hex string: 0xE6100....C0.
I want to write a query that finds all other rows in my database that have this same value. How can I do this?
I tried adding WHERE location = '0xE6100....C0' with and without quotes but I get an error:
Invalid operator for data type. Operator equals equal to, type equals geography.
Note: I'm just doing this query in an ad-hoc fashion I'm not really looking for a optimal solution or a way to parameterize this in any way. I just have a row that I'd like to find related values.
Looks like you need to use .STEquals
Check the documentation here

PostGIS point attributes to polygons, where poligon contain point

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);

Resources