17
$\begingroup$

I am using GeoGraphics to visualize electricity distribution networks in certain countries. I have susbtation location data, as well as network incidence matrices (i.e. which substations are connected to each other). From this I simply create a list of transmission lines by creating pairs of substations and putting it into a Line wrapper.

Line[{GeoPosition[{21.0112, 105.808, 0}],GeoPosition[{13.9719, 108.015, 0}]}]

In some cases though, a straight line will go through another country, or even worse over the ocean. For example, here in Vietnam.

GeoGraphics[{Line[{GeoPosition[{21.0112, 105.808, 0}], GeoPosition[{13.9719, 108.015, 0}]}], Polygon[Entity["Country", "Vietnam"]]}]

enter image description here

So my question is : How can I make a "straight" or shortest path that stays within a country? (or at least doesn't go over oceans!)

I have tried adapting this to my case but can't get it to work.

$\endgroup$
7
  • 5
    $\begingroup$ Not the fastest path but quite short solution: GeoGraphics@ TravelDirections[{GeoPosition[{21.0112, 105.808}], GeoPosition[{13.9719, 108.015}]}]["TravelPath"] $\endgroup$
    – Kuba
    Jan 19 '16 at 11:44
  • $\begingroup$ @Kuba I get an error when evaluating this. An unknown box name (TravelDirections[{GeoPosition[{21.0112, 105.808}], GeoPosition[{13.9719, 108.015}]}]) was sent as the BoxForm for the expression. Check the format rules for the expression. $\endgroup$
    – Emy
    Jan 19 '16 at 11:52
  • $\begingroup$ It's new in 10.3. $\endgroup$
    – Kuba
    Jan 19 '16 at 11:57
  • $\begingroup$ aha. I haven't made the jump from 10.2 yet. I will try it on another PC which does have 10.3 $\endgroup$
    – Emy
    Jan 19 '16 at 11:58
  • 1
    $\begingroup$ don't worry it's not a solution you are after, it doesn't give the shortest path: reference.wolfram.com/language/ref/TravelDirections.html $\endgroup$
    – Kuba
    Jan 19 '16 at 12:00
22
$\begingroup$

Here is a solution I can think of. Idea is to take the FullPolygon of a given country and then triangulate the region. Once that is done take the underlying Graph and do a FindShortestPath. Result will not be too bad.

fullPoly = CountryData["Vietnam", "FullPolygon"];
pts = Flatten[fullPoly[[1, 1]], 1];
line = Polygon[Range[##]] & @@@ Partition[{1}~Join~
 Most[Riffle[Accumulate[Length /@ #], 
     1 + Accumulate[Length /@ #]] &@fullPoly[[1, 1]]], 2];
country = Quiet@DiscretizeRegion[MeshRegion[pts, line], MaxCellMeasure -> .004]

Let's construct the Graph and find the shortest path.

graph = Graph[MeshCoordinates[country], 
MeshCells[country, 1] /. Line[{start_, end_}] -> {start, end}, 
VertexCoordinates -> MeshCoordinates[country], 
GraphLayout -> "PlanarEmbedding"];
fun = Nearest[GeoPosition[{MeshCoordinates[country]}]];
(* the start and end point you gave *)
{st, en} = Flatten[fun /@ 
{GeoPosition[{21.0112, 105.808, 0}],GeoPosition[{13.9719, 108.015, 0}]}
] /.GeoPosition[{a_, b_}] :> {a, b};
(* the shortest path *)
path = FindShortestPath[graph, st, en];
HighlightGraph[graph, PathGraph[path],GraphHighlightStyle -> "Thick"]

enter image description here

Now plotting the path on the map with little style is easy with GeoGraphics.

GeoGraphics[{Dashed, Thick, Red, Arrow@GeoPath[path, "Geodesic"], 
Orange, PointSize[0.025], Point@GeoPosition[st], Blue,PointSize[0.025],
Point@GeoPosition[en],Directive[Opacity@.05, Pink], 
Polygon[Entity["Country", "Vietnam"]]}, ImageSize -> Large]

enter image description here

The above method should work for most countries. Hope this helps.

$\endgroup$
4
  • $\begingroup$ Thanks for your great answer! Two questions: Is it me or do the paths not match perfectly? (In the GeoGraphis one, the path seems to follow the coastline for a bit, while in the graph it does not) Also, can I increase the resolution in polygons, or maybe "straighten" the line? cheers. $\endgroup$
    – Emy
    Jan 19 '16 at 16:19
  • 2
    $\begingroup$ The graph image was done with less mesh resolution (MaxCellMeasure -> .04) as it looks better and we can see the edges better. The GeoGraphics image is result of using MaxCellMeasure -> .004 which is probably a good setting for a fine mesh resolution. You are of course free to increase the resolution. Both the path will be same for a fixed MaxCellMeasure setting. $\endgroup$ Jan 19 '16 at 16:48
  • 1
    $\begingroup$ @Emy To straighten the segments of the line you'd be likely to reduce the resolution in polygons; to make the line shorter you'd increase the resolution. $\endgroup$
    – tricasse
    Jan 19 '16 at 18:12
  • $\begingroup$ @tricasse Thanks as well. That's good to know. Although I assume that with less resolution the line will be somewhat more erratic going left and right. I'll play around with this to see what better suits me. $\endgroup$
    – Emy
    Jan 20 '16 at 8:00

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.