8
$\begingroup$

I have a very large set of coordinates (40,000+) that I need to categorise in a hierarchy of geographic entities; region, country, administrative divisions, city. I only have the coordinates and no other information about them. My current approach - included below - is far to slow. It also suffers from not being able to select the city of the coordinate.

With

locs =
 GeoPosition /@ Reverse /@ RandomPoint[#, 1] & /@ 
   DiscretizeGraphics /@
    EntityValue[Keys@Select[Normal@EntityValue[RandomEntity["City", 700], "HasPolygon", 
         "EntityAssociation"], Values[#] == True &],
     "Polygon"] // Flatten

as the points. I have constructed the following.

ClearAll[geoEntityCode];
With[{
  geoCode = {
    With[{rgn = DeleteCases[Entity["GeographicRegion", "World"]]@
         EntityValue["GeographicRegion", "Entities"]},
      Pick[rgn, GeoWithinQ[rgn, #1]]] &
    ,
    With[{cntry = 
        Flatten@EntityValue[#2, {EntityProperty["GeographicRegion", 
            "Countries"]}]},
      Pick[cntry, GeoWithinQ[cntry, #1]]] &
    ,
    With[{ad1 = 
        EntityList@
         Entity["AdministrativeDivision", {EntityProperty[
             "AdministrativeDivision", "ParentRegion"] -> #2}]},
      Pick[ad1, GeoWithinQ[ad1, #1]]] &
    ,
    With[{ad2 = #2["Subdivisions"]},
      Pick[ad2, GeoWithinQ[ad2, #1]]] &
    ,
    With[{city = 
        EntityList@
         Entity["City", {EntityProperty["City", 
             "AdministrativeDivision"] -> #2}]},
      Pick[city, GeoWithinQ[city, #1]]] &
    }
  },
 geoEntityCode[pos_GeoPosition] :=
  Module[{res = ConstantArray[Missing[], 5]},
   res[[1]] = First@geoCode[[1]][pos];
   (res[[#]] =
       Check[
        First@geoCode[[#]][pos, res[[# - 1]]],
        Missing[$MessageList[[-1]]]
        ]
      ) & /@ Range[2, 5];
   res
   ]
 ]

Then

geoEntityCode@First@locs

Mathematica graphics

completes but takes far too long and gives a few errors on finding the city.

The odd thing is that Wolfram|Alpha finds this information exceptionally fast.

Mathematica graphics

How do I improve this Entity performance and have it return the city (or nearest city)? Or should I just try and grab the information from WolframAlpha?

$\endgroup$
9
$\begingroup$

I think you can use GeoIdentify for this.

The following took 40 seconds on 250 random locations (the timing is internet dependent of course).

(* locs defined from code OP provided *)
Length[locs]
250
spec = "GeographicRegion" | "AdministrativeDivision1" | "AdministrativeDivision2" | "Country" | "City";
AbsoluteTiming[
  ids = DeleteCases[GeoIdentify[spec, locs], Entity["GeographicRegion", "World"], {2}];
]
{39.465, Null}
Column[{First[locs], First[ids]}]

enter image description here

$\endgroup$
  • $\begingroup$ Big fat +1! I don't know how I missed this function. It just below GeoWithinQ so I should have seen it. This most likely is the answer. Will wait a bit for the accept just in case. $\endgroup$ – Edmund Sep 24 '16 at 22:23
  • $\begingroup$ Ok, glad it gave you what you wanted! $\endgroup$ – Chip Hurst Sep 25 '16 at 1:54

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.