# How to keep EdgeForm Thickness within GeoBoundsRegion in GeoGraphics?

I have several abutting GeoBoundsRegions that I need to colour with thick borders. The issue I am having is that EdgeForm@Thickness results in the borders being half in and half out of the regions.

GeoGraphics[{EdgeForm@Thickness[.05],
EdgeForm[Blue],
(* GeoStyling[ ... ] *)
GeoBoundsRegion[{{40.75874874700659, 40.76325125211236},
{-73.97876068957193, -73.97283921053673}}],
EdgeForm[Red],
(* GeoStyling[ ... ]  *)
GeoBoundsRegion[{{40.754248745245526, 40.75875125387347},
{-73.9737604899343, -73.9678394101969}}],
EdgeForm[Purple],
(* GeoStyling[ ... ] *)
GeoBoundsRegion[{{40.75874874700659, 40.76325125211236},
{-73.9728606895719, -73.96693921053671}}]
}]


This post (58093) suggest that there is sort of a lose work around with filled curves. However, I cannot use this solution as there is a custom GeoStyling on each of the regions.

Is there a way to only draw the EdgeForm inside (or on one side) of the border?

• If your regions are always rectangular can you not shrink them by the thickness of the border? Jul 24 '17 at 15:08
• @Mr.Wizard Wouldn't there be issues with the amount to shrink them by? There are clusters of locations at different latitudes and the distances to shrink would not be constant across all latitudes. How would the conversion from pixels as a percentage of the screen width of the map (the units of Thickness) convert to either distance units or angular degree units to effect the shrinking? Jul 24 '17 at 17:01
• Sorry, I haven't thought through these things, and I don't have GeoBoundsRegion in version 10.1 to play with. It seems like if the regions are rectangular there should be some conversion factor that would be appropriate to achieve this. As I commented on the linked Q&A this is a longstanding gap in Mathematica's* general graphics functionality and sadly there seems to be no plan to fix it. :-( Jul 25 '17 at 5:50

It turns out that I can use FilledCurve (58093) for GeoGraphics.

ClearAll[geoSquareBorder];
geoSquareBorder[
location_GeoPosition,
length_Quantity?(UnitDimensions[#] == {{"LengthUnit", 1}} &),
border_Quantity?(UnitDimensions[#] == {{"LengthUnit", 1}} &)] :=
Line@FoldList[GeoDestination, location,
{
GeoDisplacement[{First[\[FormalC] /.
Solve[{(#1)^2 + (#1)^2 == \[FormalC]^2, \[FormalC] > 0}, \[FormalC], Reals]],
"SouthWest"}, "Rhumb"],
GeoDisplacement[{#2, "North"}, "Rhumb"],
GeoDisplacement[{#2, "East"}, "Rhumb"],
GeoDisplacement[{#2, "South"}, "Rhumb"],
GeoDisplacement[{#2, "West"}, "Rhumb"]
}] & @@@ {
{length/2, length}, {length/2 - border, length - 2 border}
} // FilledCurve


geoSquareBorder passes a list of GeoDisplacements to GeoDestination to the the vertices of the square starting from the center point; hence Pythagoras for the first displacement. The list of GeoDisplacements as a second parameter is not supported but it works. I do wonder how I could get these vertices with supported syntax.

Then

GeoGraphics[{GeoStyling[],
Blue,
geoSquareBorder[GeoPosition[{40.761, -73.9758}],
Quantity[500, "Meters"], Quantity[50, "Meters"]],
Red,
geoSquareBorder[GeoPosition[{40.7565, -73.9708}],
Quantity[500, "Meters"], Quantity[50, "Meters"]],
Purple,
geoSquareBorder[GeoPosition[{40.761, -73.9699}],
Quantity[500, "Meters"], Quantity[50, "Meters"]],
}]


This creates a square with sides 500 meters with a border that extends 50 meters inward from the edge. Abutting squares no longer over-print the borders of their neighbours.

• Nice self-answer :-) Jul 30 '17 at 7:44