The problem with the US capitals example is due to the convex hull having the boundary topology of a sphere, but you’re mapping it to a planar space. A relatively simple way to work around this for visualization purposes is to include the point (0,0,0) when generating the convex hull and then drop it and any connected simplices from the resulting mesh:
In[]:=
AdaptiveGeoDelaunay // ClearAll;
In[]:=
AdaptiveGeoDelaunay[ ps_ ] := Module[ { xyzPoints, withCenter, mesh, excluded, allCells, surfaceCells }, xyzPoints = GeoPositionXYZ[ ps ][[ 1 ]]; withCenter = Prepend[ xyzPoints, { 0.0, 0.0, 0.0 } ]; (* add the center of the earth *) mesh = ConvexHullMesh @ withCenter; excluded = FreeQ[ MeshCoordinates @ mesh, { 0.0, 0.0, 0.0 } ]; allCells = MeshCells[ mesh, 2 ][[ All, 1 ]]; surfaceCells = If[ excluded, (* the center wasn't part of the convex hull, so no need to do anything *) allCells, (* delete the center vertex and shift indices *) DeleteCases[ allCells, { ___, 1, ___ } ] - 1 ]; (GeoPolygon @ Thread[ ps ][[ #1 ]] &) /@ surfaceCells ];
In[]:=
AdaptiveGeoDelaunay[ ps_GeoPosition ] := AdaptiveGeoDelaunay @ Thread @ ps;
US capitals example:
In[]:=
ps=["Position"];
In[]:=
GeoGraphics[{{EdgeForm[Blue],GeoStyling[Opacity[0.3]],RandomColor[],#}&/@AdaptiveGeoDelaunay[ps],Red,PointSize[Large],Point[ps]}]
Out[]=
This results in a mesh that automatically “wraps around” when spherical projection preserves the topology (and should be equivalent to GeoDelaunay in these cases):
In[]:=
geoDelaunayPlotter[func_]:=Function[ps,GeoGraphics[{Map[{EdgeForm[Blue],GeoStyling[Opacity[0.3]],ResourceFunction["HashHue"][Sort@#],#}&,func[ps]],Red,PointSize[Large],Point[ps]}]];
In[]:=
worldPts=Table[Thread[RandomGeoPosition[i]],{i,4,9}];
In[]:=
TableForm[Transpose@{geoDelaunayPlotter[GeoDelaunay]/@worldPts,geoDelaunayPlotter[AdaptiveGeoDelaunay]/@worldPts},TableHeadings{None,{GeoDelaunay,AdaptiveGeoDelaunay}}]
Out[]//TableForm=
GeoDelaunay | AdaptiveGeoDelaunay |
Example using only the continental US:
In[]:=
usPts=TableThreadRandomGeoPosition,i,{i,4,9};
In[]:=
TableForm[Transpose@{geoDelaunayPlotter[GeoDelaunay]/@usPts,geoDelaunayPlotter[AdaptiveGeoDelaunay]/@usPts},TableHeadings{None,{GeoDelaunay,AdaptiveGeoDelaunay}}]
Out[]//TableForm=
GeoDelaunay | AdaptiveGeoDelaunay |
