Select to view content in your preferred language

Spatial Query

1787
9
06-23-2011 11:07 AM
BrianLeroux
Frequent Contributor
In 1700 there is now a spatial query but it is not quite what i need. I am hoping to create an add-in in order to query layer based on a certain distance from from a kml point or polygon. Anyone have any ideas if this is feasible?

I was thinking I may be able to use polygon.get point on all the points and do a SearchByDistance on each point adding them to my collection.
0 Kudos
9 Replies
DarrylDempsey
Emerging Contributor
Brian,
The usual way to do this is to first buffer the query feature(s) by the distance. You follow this up with a normal spatial query for intersection (or contained in) with your buffered feature(s).

The first part is the tricky part in AGX. Buffering a point is trivial: a circle around the point. Lines and areas are non-trivial and neither is writing your own buffering function for these. (Think Minkowski Sum).  I'm not aware if there are functions in AGX or its SDK to buffer geometries.

Perhaps others can help here....
0 Kudos
DarrylDempsey
Emerging Contributor
Have done some searching in the SDK and can find no function for buffering geometries. This leaves you with a couple of alternatives (in possible order of preference);

1. Plagiarism is the sincerest form of flattery:
Search for free (rigorous) code which you can copy and/or adapt. A start would be to google 'gpc plygon'.

2. The poor man's buffer in AGX:
Create a new empty polygon. For each vertex in your query geometry create a (stroked) circle with the distance D as radius and add it to the polygon.
For each edge between vertices of your query geometry create a 4 sided polygon with 2 sides parrallel to this edge and distance D from it and add these to your polygon. The end result is a multipolygon. Use this as your query feature. (If you draw this figure in AGX without a border it should actually look like the buffered figure you need)

Good luck ...
0 Kudos
BrianLeroux
Frequent Contributor
I could not find anything in the SDK either. I think I will try to fumble through your second option to see what i can come up with. Thanks!
0 Kudos
DarrylDempsey
Emerging Contributor
Brian,
Here's some C# code to help you get started with the buffering. The methods for buffering a point and line segment are rigorous. The last could be used as the basis for buffering any line or polygon feature in AGX.

I wonder what the ESRI GeomOperations.Simply() would do to a feature made up of overlapping line segment buffers? ....
0 Kudos
BrianLeroux
Frequent Contributor
Steve-
I have not had a minute to work on this. The new spatial query in 1700 workds great with any lines or polygons. I wish I had the code to incoporate into my add-ins. Anyway, if you could share the vb.net version of the code Darryl supplied it would be greatly appreciated and save me some time.

Thanks!
0 Kudos
DarrylDempsey
Emerging Contributor
Hi Brian and Steve,
First the good news: I've almost finished the buffer utility. It rigorously buffers points, multipoints, polylines and envelopes. For polygons it does what I call an outer buffer, which means it ignores holes.
To do this sort of thing you basically need 3 things: a powerful, rigorous planarizer, a Dcel (doubly connected edge list) and a Plane Sweep through the Dcel.
I had the last two (in C++) and altered them for C#.
One of the best kept secrets in AGX is that the GeometryOperations.Simplify() method is a perfect and extremely fast planarizer.

Now the bad news: I can't program in Basic and do everything in C, C++ or C#.

Will post the code this weekend, after a bit more testing.
0 Kudos
DarrylDempsey
Emerging Contributor
Hi Steve,
Your theory is sound as far as it goes. The devil is in the detail, as an English statesman said.
Here's the code.
The function parameter r is the buffer distance and tol is the maximum amount a stroked arc chord shoud deviate from the arc (bulge in CAD parlance). Both must be positive and r >= tol.

The public functions Buffer() for points, multipoints, envelopes and single line segments are rigorous.

The public functions OuterBuffer() for polygons and polylines do not take holes into account and in the case of closed polylines or polylines where the buffer is large enough to partly overlap itself, what should be a do-nut turns into a pizza.

In any case it's more than the poor man's buffer and very fast. If time and interest permit I'll work on a rigorous version for polylines and polygons.

There's also a function included which does a Douglas-Peucker generalization of polylines/polygons.
I use it to remove degeneracies before buffering, but it's probably handy in it's own right.
0 Kudos
DarrylDempsey
Emerging Contributor
Steve,
The units for r and tol must be in the SAME units as your input geometry, otherwise you'll be multiplying apples by pears. If the coordinates of your input are in feet then r and tol must also be in feet. Same goes for input geometry in meters or whatever.

The signature for buffering a point, multipoint, envelope is
Buffer(<a point, multipoint, envelope>, r, tol).

The signature for buffering a single line segment is
Buffer(begin point, end point, r, tol).

The signature for polylines and polygons is
OuterBuffer(< polyline, polygon>, r, tol).

Don't worry about the complexity of the code under the bonnet. Just drive the car. Hope you have a good ride
0 Kudos
DarrylDempsey
Emerging Contributor
A week is a long time in politics and AGX.

I found a great implementation of the Vaati clipping algorithm in C# (Clipper) on the internet, which made it possible without much trouble to implement efficient and rigorous buffering for all feature types in AGX. See the file clipper.cs for the site information and copyright.

Enclosed is the C# code. The geometry polygon operations union, intersection, difference and xor are now also available for AGX in this code.

If I have time I'll make a series of Addins which will operate on the layers and notes in AGX.
0 Kudos