5
$\begingroup$

GeoWithinQ is a very useful function - is this point within this area? However, it is quite slow. It's not unheard of to have large numbers of points - for instance, global satellite measurements at a high resolution. I have used satellite data with millions of pixels - ie, data points.

Let's say I have 100,000 points and I would like to check whether they are within the polygon of France. However, doing

points = RandomGeoPosition[100000]
Select[points, GeoWithinQ[Entity["Country","France"]]]

times out. The documentation has another example that uses Pick instead of Select.

Pick[points, GeoWithinQ[Entity["Country","France"], points]

This too times out, but it is significantly faster for a smaller number of points (I've managed about 1,000 before hitting major performance issues).

My question is, how do I use GeoWithinQ for 100,000 points and more?

$\endgroup$
5
$\begingroup$

You can use RegionMember and the region functionality to make this a lot faster, at the expense of a smaller functionality, and potentially missing out some details about geodesy, as well as losing out on GeoModel and the like. This approach also doesn't use the network (other than getting the entity's polygon), so it is better suited for network-constrained development. (GeoWithinQ actually uses the network!)

We generate our points:

points = Thread@RandomGeoPosition[100000]

(we Thread here so we have 100,000 GeoPosition objects rather than one GeoPosition object with 100,000 sub-points)

Then, we set up a RegionMemberFunction using the polygon for France. We strip the GeoPosition heads out of the Polygon, because RegionMember can't work with them:

rm = RegionMember[
  Entity["Country", "France"]["Polygon"] /. GeoPosition[x_] -> x]

and then we Select based on this RegionMemberFunction, again stripping the GeoPosition head out.

Select[points, rm[# /. GeoPosition[x_] -> x] &]

This takes about 5 seconds on my machine.

Pick in this case is even faster:

Pick[points, rm[points /. GeoPosition[x_] -> x]]

which takes just over a second on my machine.

It's a pity that GeoWithinQ doesn't have PerformanceGoal or similar so that we can ask it to be less exact, but faster.

| improve this answer | |
$\endgroup$

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.