Suppose I want to VectorPlot
on a geographic map a vector field defined on a Reference Ellipsoid.
The field is given to the following function as a f_
(or {fx_, fy_}
) whose two components are the latitudinal and longitudinal components.
Following the approach I used to ContourPlot
a scalar field I can end with a code like this:
SetAttributes[GeoGraphicsVectorPlot, HoldAll]
Options[GeoGraphicsVectorPlot] = {
"GeoGraphicsOptions" -> {},
"PlotCellsCount" -> 10000
};
SyntaxInformation[
GeoGraphicsContourPlot] = {"LocalVariables" -> {"Solve", {2, 2}}};
GeoGraphicsVectorPlot[f_, gcoords : {Repeated[_Symbol, {3}]},
opts : OptionsPattern[]] :=
Module[{geog, datum, proj, geogpol, mesh, coords, vlp, vlc, fl, fail,
pvl, plotType, plotOptions, plot, plotPrimitives},
geog = GeoGraphics[{}, OptionValue["GeoGraphicsOptions"]];
{datum, proj} = {GeoModel, GeoProjection} /.
AbsoluteOptions[geog, {GeoModel, GeoProjection}];
geogpol =
First@Cases[geog,
Polygon[vl_, ___, VertexTextureCoordinates -> _, ___] :>
Polygon@vl, \[Infinity]];
mesh = DiscretizeRegion[geogpol,
MaxCellMeasure -> Area@geogpol/OptionValue["PlotCellsCount"]];
coords = MeshCoordinates[mesh];
vlp = GeoGridPosition[coords, proj, datum];
vlc = GeoPositionXYZ[vlp];
fl = With[{n = Length@gcoords},
Map[Block[gcoords, gcoords = Take[#, n]; f] &, vlc[[1]]]];
pvl = Transpose@{coords, fl};
pvl = adjustVectorField[proj, datum] /@ pvl;
plot = ListVectorPlot[pvl];
MapAt[{{#}, plot[[1]]} &, Graphics @@ geog, {1}]
]
adjustVectorField[proj_, datum_] := Identity
GeoGraphicsVectorPlot[{1, 2}, {x, y, z},
"GeoGraphicsOptions" -> {GeoRange -> "World", GeoModel -> "GRS80",
GeoProjection -> "Mercator"}]
GeoGraphicsVectorPlot[{1, 2}, {x, y, z},
"GeoGraphicsOptions" -> {GeoRange -> "World", GeoModel -> "GRS80",
GeoProjection -> "Equirectangular"}]
The tricky part, with respect to the scala field, is how to properly compute the projected direction of the field, i.e. how to define the family of functions adjustVectorField[proj_, datum_]
so that it works on many (ideally all) map projections.