18
$\begingroup$

A friend said to me on Facebook that she is 4000km away. So I want to try to guess where she is.

How can I find which countries are a given distance from my current location?

$\endgroup$
7
  • 5
    $\begingroup$ Close reason: Wolfram|Alpha questions not related to Mathematica are off topic here. Ask on community.wolfram.com instead. $\endgroup$
    – Szabolcs
    Jun 14, 2014 at 15:16
  • $\begingroup$ @Szabolcs, I think this is an interesting question (we don't have any other answers on the site using GeoDestination) so I edited it to not be about W|A any more. $\endgroup$ Jun 14, 2014 at 19:33
  • $\begingroup$ @Szabolcs I don't see why this is a W|A question. Mathematica has the tools (and will even have more in v10) to solve this question. I vote to reopen $\endgroup$ Jun 14, 2014 at 19:34
  • $\begingroup$ @SjoerdC.deVries Because the OP specifically asked about Wolfram|Alpha (see the first version), and there's a good chance he might not even have Mathematica. The question has been edited now. While a Mathematica solution might not be useful for the OP, I agree that it is interesting, and it can be reopened, as others might ask the same. $\endgroup$
    – Szabolcs
    Jun 14, 2014 at 19:55
  • $\begingroup$ @szabolcs I interpreted the first version as saying that W|A did not give an answer so that it was now up to Mathematica to come up with something. It might be that the OP was looking for a better way to ask W|A this. I guess both interpretations could be valid based on the rather ambiguous question. $\endgroup$ Jun 14, 2014 at 20:11

3 Answers 3

23
$\begingroup$

Thanks to Simon Woods' advises it should now be correct.

Taking the OP's informations:

loc = {46.72, 25.59};(*CityData["Gheorgheni","Coordinates"]*); 
dist = 4*10^6;(*distance in m*)

bounds = Table[GeoDestination[loc, {dist, i}][[1]], {i, 0, 360, 1}];
Graphics[{EdgeForm@Thin, Red, Polygon[Reverse /@ bounds], [email protected],
    EdgeForm[Thin], FaceForm[LightGray], 
    Tooltip[CountryData[#, "SchematicPolygon"], #] & /@ CountryData[]}, 
  ImageSize -> 700]

Mathematica graphics

Of course, the same can be done with your own location: loc = $GeoLocation.

GeoDistance[loc, #] & /@ bounds are then all equal to 4000 km.


Checking which countries are exactly on the 4000 km border (and thanks to rm-rf answer here):

countriesCoor = 
  First /@ (CountryData[#, "Coordinates"] & /@ CountryData[]);
inPolyQ[poly_, pt_] := Graphics`Mesh`PointWindingNumber[poly, pt] =!= 0
crossedCountriesPos = 
  Flatten@DeleteDuplicates[
    Table[Position[inPolyQ[#, bounds[[i]]] & /@ countriesCoor,True], 
      {i, 1, Length@bounds, 1}] /. {} :> Sequence[]];
crossedCountries = CountryData[][[#]] & /@ crossedCountriesPos;
crossedCountries // Short
insideCountries = CountryData[][[#]] & /@ 
  Flatten@Position[
  inPolyQ[bounds, #] & /@ (CountryData[#, "CenterCoordinates"] & /@
  CountryData[]), True];
insideCountries // Short

Countries lying on the 4000 km border:

{Russia,Kazakhstan,China,Kyrgyzstan,Pakistan,Oman,Yemen, <<5>>, Chad,Cameroon,Nigeria,Niger,Mali,Mauritania,WesternSahara}

Countries inside the 4000 km area:

{Afghanistan,Albania,Algeria,Andorra,Armenia,<<73>>, UnitedArabEmirates,UnitedKingdom,Uzbekistan,VaticanCity,WestBank}

Graphics[{EdgeForm@Thin, Red, Polygon[Reverse /@ bounds], [email protected],
    Black, CountryData[#, "SchematicPolygon"] & /@ insideCountries, Blue, 
    CountryData[#, "SchematicPolygon"] & /@ crossedCountries, 
    FaceForm[Lighter@LightGray], 
    Tooltip[CountryData[#, "SchematicPolygon"], #] & /@ CountryData[]}, 
  ImageSize -> 700]

Mathematica graphics

$\endgroup$
10
  • $\begingroup$ Except the radius of that circle isn't 4000km? $\endgroup$ Jun 14, 2014 at 17:15
  • $\begingroup$ Shouldn't the disk be also distorted like the map projection, or is that taken into account with geodestination ? $\endgroup$
    – lalmei
    Jun 14, 2014 at 17:33
  • $\begingroup$ @blochwave I'm afraid that you are right indeed :) GeoDistance[loc, endCircle] doesn't even return 4000km. $\endgroup$
    – Öskå
    Jun 14, 2014 at 17:44
  • 2
    $\begingroup$ Looks like version 10 has this built in :-) $\endgroup$ Jun 14, 2014 at 18:49
  • 2
    $\begingroup$ @Öskå - Hopefully, Boti's new friend doesn't live in Vatican-City. $\endgroup$
    – eldo
    Jun 14, 2014 at 22:23
15
$\begingroup$

Using the new geographic tools in Mathematica 10:

GeoGraphics[
 GeoCircle[
  GeoPosition[Entity["City", {"Gheorgheni", "Harghita", "Romania"}]
   ],
  Quantity[4000, "km"]
  ],
 GeoBackground -> "StreetMap", (* To get country labels *)
 ImageSize -> 800
 ] 

enter image description here

WRI posted another example on Twitter.

There is another tool called GeoIdentify that returns all regions of the selected type that a path crosses. This can give us a list of countries to complement our visualization:

countries = GeoIdentify[
 "Country",
 GeoCircle[
  GeoPosition[Entity["City", {"Gheorgheni", "Harghita", "Romania"}]
   ],
  Quantity[4000, "km"]
  ]
 ]

Out:

list of countries

The GeoIdentify documentation has some ideas about how visualize this as well. Combining our previous code with this styling gives us:

geocircle = GeoCircle[
   GeoPosition[Entity["City", {"Gheorgheni", "Harghita", "Romania"}]
    ],
   Quantity[4000, "km"]
   ];
GeoGraphics[{
  (Tooltip[{GeoStyling[Opacity[.5]], RandomColor[], Polygon[#1]}, CommonName@#1] &) /@ countries,
  geocircle
  },
 GeoRange -> geocircle,
 ImageSize -> 800
 ]

Stylish map

If you think Spain doesn't look like it intersects the circle, recall the position of the Gran Canary Islands. (Since it is a popular tourist destination it's a good guess that that is where the OP's friend is.)

EDIT: Since the animation was generated I have replaced the tooltips according to rcollyers suggestion. The tooltip label is now the CommonName of the country entity instead of the entity itself (labels now look the way you expect them to.)

$\endgroup$
5
  • $\begingroup$ It would be nice to also list the countries in addition to plotting them. Are there v10 tools for this? (I don't know.) $\endgroup$
    – Szabolcs
    Jul 22, 2014 at 12:52
  • $\begingroup$ @Szabolcs Well, you inspired me to keep looking and it turns out there is :) $\endgroup$
    – C. E.
    Jul 22, 2014 at 13:10
  • 1
    $\begingroup$ Good use of v10! +1 $\endgroup$ Jul 22, 2014 at 13:18
  • $\begingroup$ Might I suggest you use CommonName@# for the second argument in Tooltip? Oh, and you already had my +1. $\endgroup$
    – rcollyer
    Jul 22, 2014 at 18:06
  • 1
    $\begingroup$ @rcollyer Thanks, I updated the code and wrote a short paragraph about this change. $\endgroup$
    – C. E.
    Jul 22, 2014 at 18:12
3
$\begingroup$

I am assuming you have Mathematica with you. So here's some quick and dirty way to get the info you require. I think it is very interesting to do this

currentLocation = 
 GeoPosition[
   CountryData[
     StringTrim[
      StringSplit[
        WolframAlpha[
         "Current GeoIP location", {{"HostInformationPod", 1}, 
           "ComputableData"}][[2, 2]], ","][[3]]], "CenterCoordinates"]];

 countries = CountryData[];
 geopos = GeoPosition[CountryData[#, "CenterCoordinates"]] & /@ countries;
 distances = GeoDistance[currentLocation, #] & /@ geopos;
 countriesAround4000km = CountryData[][[#]] & /@  Position[distances, _?(# < 4.1*10^6  && # > 3.9*10^6 &)]
$\endgroup$
4
  • 1
    $\begingroup$ $GeoLocation is easier than the W|A call. $\endgroup$
    – Öskå
    Jun 14, 2014 at 16:04
  • $\begingroup$ I agree but it showed me wierd results at my end. Ok you can also try your approach if it works for you currentLocation = GeoPosition[FindGeoLocation[]]; without WA call $\endgroup$
    – arvind
    Jun 14, 2014 at 16:10
  • $\begingroup$ Well, both don't give the same location. $\endgroup$
    – Öskå
    Jun 14, 2014 at 16:11
  • $\begingroup$ Agree.. the first approach derives the country of IP and then computes the center coordinates and other gives the current coordinates. Of course, a more detailed approach can be used $\endgroup$
    – arvind
    Jun 14, 2014 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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