3

I'm work with the NTS(NetTopologySuite), I get large amounts of Point geometries, for fast querying the point object, I make the STRtree Index like this,

STRtree tree = new STRtree(); foreach (var p in allPoint) { tree.Insert(p.EnvelopeInternal, p); }

While some point objects in the "allPoint" change it's position. And I find I can't query the point which change position anymore..

How to work with it?

Thanks.

1

There are a couple of reasons why what you're trying to do here won't work.

  1. As dpp pointed out, you need to delete / reinsert changed coordinates on the index once something moves around. Otherwise, the index has no way of knowing that its cached metadata is dirty.
  2. Items cannot be inserted into an STRTree once it has been built, so it's not suitable for things that are constantly shifting around.

Quadtree is similar to STRTree and does support on-the-fly insert / remove operations. It's slower, but still OK in practice.

However, all that aside, is there some reason why you need the actual Point instead of just Coordinates? If Coordinate is OK or if you're fine with creating Point objects later on, then Dictionary<Coordinate, int> just seems like a much simpler solution than a spatial index.

Dictionary<Coordinate, int> coordinateMapping = new Dictionary<Coordinate, int>();

// to insert a new coordinate:
int n;
if (!coordinateMapping.TryGetValue(coordinateToInsert, out n))
{
    n = 0;
}
coordinateMapping[coordinateToInsert] = n + 1;
// now future queries will tell you how many of that coordinate are present.

// to determine how many of a given coordinate are present:
int n;
coordinateMapping.TryGetValue(coordinateToQuery, out n);
// check "n" for how many copies of that coordinate are present.

// to remove one of the coordinates from the index:
int n = coordinateMapping[coordinateToRemove];
// the above throws KeyNotFoundException if the coordinate was not present.
if (n == 1)
{
    coordinateMapping.Remove(coordinateToRemove);
}
else
{
    coordinateMapping[coordinateToRemove] = n - 1;
}
0

I believe the only option you have is to delete/reinsert once a coordinate has changed.When the point is inserted, the tree takes into account its envelope which in turn is computed based on the point's coordinates.So when you change the point's coordinates, the point will have a new bounding box.In fact, in JTS you cannot change the coordinates of a Point once created.It's possible to do so for a Coordinate but it doesn't really maintain the envelope as it's said to be a 'lightweight' geometry just storing coordinate pairs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.