Softanza
StartFrançais
Softanza
The library documents itself · Geo & cartography

stzGeoMap

113 own methods · 27 forms written with extensions, listed under their method

the source: base/geo/stzGeoMap.ring(opens in a new tab) · All classes · The area reference: Geo & cartography

Under each method, its extensions (Q CS XT Z ZZ IB W U): bold and ticked, it exists; struck, it does not. The extensions and what they mean

Examples: 0 come from the library's tests; 31 were composed from each method's signature and run for this page, on a fresh object, for example cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}' oF = StzGeoFeaturesFromJson(cJ) o1 = StzGeoMap(new stzGeoProjection(:mercator), oF). 82 methods have none yet. Examples run on 2026-10-03 20:51 inside the library at commit 0e72e2e2c.

Method
Explanation, as the source carries it
Bind
(no comment in the source: the name reads as a sentence) bindno extension
Projection
(no comment in the source: the name reads as a sentence) projectionno extension
Features
(no comment in the source: the name reads as a sentence) featuresno extension
SetValues
what is being shown ------------------------------------------------- one value per feature, in the features' own order; "" where the map has a hole. A region with no value is DRAWN as no data and says so in the legend -- it is never quietly coloured as zero.QCSXTZZZIBWU
ValuesFromArea
every feature's own true area in square kilometres, measured on the SPHERE from its rings -- a value that needs no other file, and the one an equal-area projection can be checked against
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? @@( o1.ValuesFromArea() )
#--> [ 196869.60 ]
composed from the signature, run for this page
no extension
ValueOf
(no comment in the source: the name reads as a sentence) value ofno extension
SetClasses
(no comment in the source: the name reads as a sentence) set classesQCSXTZZZIBWU
SetRamp
the palette by the name of a ramp, in the classes already setQCSXTZZZIBWU
SetPalette
(no comment in the source: the name reads as a sentence) set paletteQCSXTZZZIBWU
SetPaper
where the boundaries came from and when. A map asserts where a border lies; this class will not invent the authority for it. THE BOX THE MAP WAS DRAWN IN, so a name cannot be written off the edge of it. Without this the label engine only knows where a region is, not where the sheet ends, and the first version wrote "Diffa" half into the margin beside it. Unset, nothing is clipped.QCSXTZZZIBWU
SetNoData
THE COLOUR OF A REGION NO CLASS AND NO GROUP CLAIMS. It is a real statement -- "this one is not in the data" -- and a caller drawing a bloc map wants it quieter than the default, because on that sheet the unclaimed countries are most of the world.QCSXTZZZIBWU
SetHatch
THE COLOUR OF THE HATCH THAT SAYS "NOT MEASURED", on the map and in the legend's swatch, which are one thing and read from one place. The default is a blue-grey: cool, so it cannot be mistaken for a step in a warm ramp, and light, so a hatched country does not out-shout a measured one.QCSXTZZZIBWU
Hatch
(no comment in the source: the name reads as a sentence) hatch
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.Hatch()
#--> #9EB6D8
composed from the signature, run for this page
no extension
SetOpenTop
IS THE TOP CLASS OPEN -- "30 and over" rather than "20 to 30". It is a statement about the SCALE, so it lives with the scale and not in the legend's argument list: the classifier and the legend both read it, and a reader must never meet an arrow the map refused to fill.QCSXTZZZIBWU
IsOpenTop
(no comment in the source: the name reads as a sentence) is open top
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.IsOpenTop()
#--> 0
composed from the signature, run for this page
no extension
SetSource
(no comment in the source: the name reads as a sentence) set sourceQCSXTZZZIBWU
SetGroups
paGroups is [ [ label, colour, [ member names ] ], ... ]. A country in two groups belongs to the FIRST that claims it, and that is reported too: overlapping blocs are a fact a reader must be told, not a tie for this file to break quietly.QCSXTZZZIBWU
Groups
(no comment in the source: the name reads as a sentence) groupsno extension
GroupOf
which group claimed this feature, or 0 for none
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.GroupOf(2)
#--> 0
composed from the signature, run for this page
no extension
UnresolvedMembers
[ [ :group, :name ], ... ] -- every member name that matched no featureno extension
IsGrouped
(no comment in the source: the name reads as a sentence) is grouped
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.IsGrouped()
#--> 0
composed from the signature, run for this page
no extension
DrawGroupKeyOn
the key a membership map owes: one swatch and one label per group, with the count it actually DREW rather than the count it was handedno extension
ClassOf
(no comment in the source: the name reads as a sentence) class of
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.ClassOf(2)
#--> 0
composed from the signature, run for this page
no extension
ColourOf
(no comment in the source: the name reads as a sentence) colour of
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.ColourOf(2)
#--> #E8E8E8
composed from the signature, run for this page
no extension
DrawOn
the layers ---------------------------------------------------------- the sphere, the graticule, then every feature in its class's colour, then the world's edge on top: the order an atlas draws them inQCSXTZZZIBWU
DrawSphereOn
(no comment in the source: the name reads as a sentence) draw sphere onno extension
DrawGraticuleOn
(no comment in the source: the name reads as a sentence) draw graticule onno extension
DrawRegionsOn
every feature, in the colour its value earns itno extension
HighlightOn
one feature picked out, over the restno extension
DrawSymbolsOn
symbols ------------------------------------------------------------- A CIRCLE'S AREA CARRIES THE VALUE, NEVER ITS RADIUS. Doubling a radius quadruples the ink, so a symbol map scaled by radius overstates its largest places fourfold -- the oldest lie in the genre, and the one a reader cannot see being told. The radius here is proportional to the SQUARE ROOT of the value, so equal values draw equal ink.no extension
DrawSymbolAt
a symbol at a place the caller names, rather than at a featureno extension
CentroidOf
the middle of a feature's largest part, in longitude and latitude: the mean of its outer ring, which is where a symbol belongs and is NOT where a label belongs on a crescent-shaped countryno extension
HexBin
The points arrive as longitude and latitude and are PROJECTED first, so the bins are cells of the paper. That is d3's choice too, and the map's own rules say what it costs on a projection that distorts area.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? @@( o1.HexBin([ 2, 3 ], 2) )
#--> [ [ 486.71, 243, 1 ] ]
composed from the signature, run for this page
no extension
DrawHexBinsOn
the bins drawn, each in the colour its COUNT earns from the edges given. A bin holding nothing is not drawn: an empty cell is not a quantity of zero, it is a place nobody counted.no extension
HexBinMax
the biggest count in a set of bins -- what a legend's last edge wantsno extension
DrawFlowsOn
flows --------------------------------------------------------------- A FLOW IS A GREAT CIRCLE, not a straight line on the paper: the route between two places bends on every projection, and drawing it straight is drawing a journey nobody takes. Each route is [ lon1, lat1, lon2, lat2 ] or the same with a width as a fifth item.no extension
AssignPoints
THIS IS THE SPATIAL JOIN, and it is the whole of spatial analytics' first step: a table of places -- wells, clinics, rain gauges, sales -- each with a longitude and a latitude, and the question "how many in each region". Nothing about it is a picture yet. which feature each point fell in, one index per point, 0 for a point outside every one of them. A point outside is NOT an error and not rounded to the nearest region: it is reported as 0, because a well across the border belongs to the other side.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? @@( o1.AssignPoints([ 2, 3 ]) )
#--> [ 1 ]
composed from the signature, run for this page
no extension
CountPointsIn
how many points fell in each feature, in the features' own order -- which is exactly the shape SetValues takes, so a table of coordinates becomes a choropleth in two calls
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? @@( o1.CountPointsIn([ 2, 3 ]) )
#--> [ 1 ]
composed from the signature, run for this page
no extension
PointsOutside
...and how many fell outside every region, which a caller must be told rather than left to notice that their totals do not add up
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.PointsOutside([ 2, 3 ])
#--> 0
composed from the signature, run for this page
no extension
DensityPointsIn
the same counts, divided by each region's own area in square kilometres: a DENSITY, which is the number a choropleth may honestly colour. A count may not -- a big region collects more of anything -- and that is the commonest lie in the genre after the radius one.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? @@( o1.DensityPointsIn([ 2, 3 ]) )
#--> [ 0.05 ]
composed from the signature, run for this page
no extension
SamplePointsInside
The sequence is the caller's seed, so the same call gives the same places every time -- a committed picture that moves on every render is a diff nobody can read. And the answer is INVENTED DATA: the caller who draws it owes their reader that word, which is why the map's caption takes a source line.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? @@( o1.SamplePointsInside(2, 5) )
#--> [ 0.85, 1.78, 3.55, 3.82 ]
composed from the signature, run for this page
no extension
LabelPointOf
labels --------------------------------------------------------------- WHERE A NAME GOES. The mean of a ring is not inside it whenever the region is a crescent, a horseshoe or a pair of islands -- and a label outside its own region is a label on somebody else's. So the mean is TRIED and, when it lands outside, an interior point is searched for: the point of a coarse grid that is inside and furthest from the edge, which is the pole of inaccessibility a cartographer would use, taken at a resolution a map at this size cannot tell from the exact one.no extension
LabelFloor
What is not here, named: INSETS. A zoomed box for Grand Tunis or the Ile-de-France is how an atlas rescues the numbers this drops, and it is the next step, not this one. THE SMALLEST TYPE THIS WILL DRAW. The Principal has returned a picture for unreadable text once per plane; a label below this is not a label.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.LabelFloor()
#--> 13
composed from the signature, run for this page
no extension
LabelReport
WHAT THE LABELLING DID, in four numbers that add up to the feature count. `unlisted` is the one that was nearly left out: entries the key box had no room for. A key that runs off the bottom of its box loses names SILENTLY, and the first version of DrawKeyOn did exactly that -- 39 of France's 75 entries drawn and 36 gone, under a comment in this same file claiming a key must never do that. So it is counted here and the gate refuses it.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? @@( o1.LabelReport() )
#--> [ [ "named", 0 ], [ "numbered", 0 ], [ "inset", 0 ], [ "dropped", 0 ], [ "unlisted", 0 ] ]
composed from the signature, run for this page
no extension
SetKeyBox
where the key is written: [ x0, y0, x1, y1 ]. With no key box set, a region that cannot carry its own name is dropped -- a number with nothing to look it up in is worse than a blank.QCSXTZZZIBWU
SetKeyTitle
(no comment in the source: the name reads as a sentence) set key titleQCSXTZZZIBWU
SetKeyCodes
OFF BY DEFAULT, and deliberately: official codes are not in reading order, so "08" sitting beside "59" tells a reader who does not already know them nothing about where to look. Sequential in reading order is the atlas default; the code is for a sheet drawn for people who are at home in it.QCSXTZZZIBWU
SetLabelMode
THE MODE IS THE CALLER'S AND NEVER THE ENGINE'S, because the right answer depends on who is reading. A sheet for people who know the country wants :Names; a plate in a report wants :Numbers; a screen where one region is huge and its neighbour is a city wants :Auto.QCSXTZZZIBWU
LabelMode
(no comment in the source: the name reads as a sentence) label mode
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.LabelMode()
#--> auto
composed from the signature, run for this page
no extension
KeyEntries
(no comment in the source: the name reads as a sentence) key entriesno extension
PlacedBoxes
EVERY BOX THE LAST LABELLING PUT DOWN, as [ x0, y0, x1, y1 ]. Exposed so a guard can assert the MECHANISM rather than a number that agrees with it by accident: the suite used to check "fewer regions were named than exist", which passes just as well when nothing was drawn at all. With the boxes in hand it can test every pair and prove they are disjoint.no extension
DrawLabelsOn
(no comment in the source: the name reads as a sentence) draw labels onno extension
DrawLabelsWithValuesOn
(no comment in the source: the name reads as a sentence) draw labels with values onno extension
DrawLabelsXT
(no comment in the source: the name reads as a sentence) draw labels xtno extension
KeyReachPixels
HOW FAR OUTSIDE ITS REGION A NUMBER MAY BE SET, in pixels. Sixteen is about a line of type: far enough to clear a border stroke and the region's own neighbour, near enough that no reader has to decide which of two regions a number belongs to.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.KeyReachPixels()
#--> 16
composed from the signature, run for this page
no extension
PaperCentreOf
THE CENTRE OF A REGION ON THE PAPER: the area centroid of its largest part's outline, projected. This is the point a name goes at when it fits there, and the point a reader checks the placement against.no extension
DrawKeyOn
THE KEY, in as many columns as its box will carry. A key that runs off the bottom of its box is a key that lost entries silently, so the column width comes from the widest entry ACTUALLY PRESENT and the row count from the box's own height.no extension
InkOver
This used to ask StzIsDarkColor and choose white or the caller's ink, and it put black names on dark blue and dark red -- which the Principal returned twice. The house HAS a contrast contract: StzReadableTextOn(background, sizePx, bold) answers the ink AND whether that size can carry it, measured against WCAG's 4.5:1 for normal text and 3:1 for large. A drawing file has no business having its own opinion about contrast when the colour system holds one.no extension
PaperBoxOf
a region's box ON THE PAPER: what the reader's eye measures a name against, which is not the box it has on the sphereno extension
SetInsetInk
AN INSET LABELS THE WAY ITS PARENT LABELS ITS UNITS -- names, or the parent's official codes where it has them, and never a sequential number, which would need a second key and a sheet with two keys has given up. If a mark still will not fit at the inset's scale it is REPORTED, and the answer is a larger box, not a cleverer placement.QCSXTZZZIBWU
SetInsetPaper
(no comment in the source: the name reads as a sentence) set inset paperQCSXTZZZIBWU
AddInset
paWindow is the ground to magnify, [ lon0, lat0, lon1, lat1 ]; paBox is where it goes on the canvas, [ x0, y0, x1, y1 ].QCSXTZZZIBWU
Insets
(no comment in the source: the name reads as a sentence) insetsno extension
InsetHolding
the FIRST inset holding it, and not the nearest: two insets over the same ground is a mistake the caller should see, not a tie to break here
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.InsetHolding(2)
#--> 0
composed from the signature, run for this page
no extension
InsetReports
(no comment in the source: the name reads as a sentence) inset reportsno extension
DrawInsetsOn
(no comment in the source: the name reads as a sentence) draw insets onno extension
SetHighlight
1. BORDERS ARE DARK AND THIN, NOT WHITE. A white border between two pale classes erases the boundary exactly where the map is doing its work; a hairline of the ink colour separates them at every shade. Our World in Data, the Financial Times and the Economist all stroke dark, and the reason is legibility at the light end. 2. THE LEGEND IS A RAMP WITH ITS EDGES LABELLED, not a stack of "10 to 20" rows. A reader matches a colour to a position on a bar, and the numbers belong at the JOINS because that is where the meaning changes. It carries a NO-DATA swatch, hatched, so "not measured" is visibly not a value. 3. WHAT IS SELECTED IS OUTLINED, NOT RECOLOURED. Recolouring a selection destroys the one thing the map encodes. A heavy dark outline says "this one" while leaving its class readable. 4. TEXT OVER COLOUR NEEDS A HALO. A white name on a mid-orange is unreadable at every size; the same name with a thin dark halo is readable on every shade in the ramp. This is the colour system's contrast contract solved the way cartographers solve it, since a label on a choropleth has no single background to contrast with. the regions to outline heavily: by name, or by class through HighlightClass belowQCSXTZZZIBWU
HighlightClass
SELECT A WHOLE CLASS, which is what clicking a legend swatch means: "show me everyone between 2 and 5 per cent". The class is outlined on the map AND framed in the legend, so the two read as one gesture.QCSXTZZZIBWU
Highlighted
(no comment in the source: the name reads as a sentence) highlightedno extension
IsHighlighted
(no comment in the source: the name reads as a sentence) is highlighted
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.IsHighlighted(2)
#--> 0
composed from the signature, run for this page
no extension
SetInteractive
EVERY REGION CARRIES ITS OWN IDENTITY INTO THE SVG, which is what an interactive layer is made of: an id a script can address, a class a stylesheet can hover, and a <title> the browser shows as a tooltip with no script at all. The diagram plane has had this since DN3b; a map is the surface that wants it most, because a reader's first question of any choropleth is "which country is that and what is its number".QCSXTZZZIBWU
IsInteractive
(no comment in the source: the name reads as a sentence) is interactive
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.IsInteractive()
#--> 0
composed from the signature, run for this page
no extension
IdentOf
the id a region takes in the SVG: its name, lowercased, with anything that is not a letter or a digit turned into a hyphenno extension
DrawSheetOn
THE REGIONS, DRAWN THE WAY A STATISTICAL MAP DRAWS THEM: dark hairline borders, the highlighted ones outlined heavily on top, and each one carrying its identity when the map is interactive.no extension
DrawHighlightOn
the heavy outline, drawn OVER everything so a neighbour cannot cover itno extension
DrawNoDataHatchOn
The lines are CLIPPED TO THE SHAPE, by the same routine for a country and for the legend's own swatch. The first legend swatch drew its hatching as unclipped diagonals and they ran out of the box on both sides -- "its rectangle in the legend is not correct", which it was not. One clipper, two callers, and no second definition of a hatch.no extension
IsUnclassed
NO DATA MEANS NO VALUE, and it does not mean "a value my scale has no box for". A country measured at 35 on a scale topping out at 30 is data -- badly classed data, which is the cartographer's problem and not the country's -- and hatching it would tell the reader nobody counted it. So this asks for the VALUE where the map is numeric, and for membership where the map is categorical, since a map cannot be both.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.IsUnclassed(2)
#--> 0
composed from the signature, run for this page
no extension
HasThematicLayer
is this map ABOUT something, or is it the ground under one?
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.HasThematicLayer()
#--> 0
composed from the signature, run for this page
no extension
NoDataCount
(no comment in the source: the name reads as a sentence) no data count
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.NoDataCount()
#--> 0
composed from the signature, run for this page
no extension
DrawNamedLabelOn
IT RETURNS FALSE AND DRAWS NOTHING rather than placing a label that does not fit. A name that will not fit inside its region lands on a neighbour, and a label on the wrong region is worse than no label -- it is a false statement, where silence is only a missing one.no extension
DrawHaloTextOn
(no comment in the source: the name reads as a sentence) draw halo text onno extension
DrawRampLegendOn
WHETHER THE TOP IS OPEN IS NOT AN ARGUMENT HERE. It used to be, and that made two places answer one question: the legend drew an arrow saying "30 and over" while the classifier, which had never been told, answered NOTHING for 35 and the map drew that country as no data. It is SetOpenTop now -- declared once with the scale, read by the classifier and by this method, and it cannot be set after the map is drawn.no extension
DrawScaleBarOn
Answers the y it ended at, or 0 if it drew nothing.QCSXTZZZIBWU
ScaleVariation
WOULD A SCALE BAR BE HONEST ON THIS MAP? The ratio of the largest local scale on the sheet to the smallest. 1 means a bar is true everywhere; anything much above it means the bar is decoration.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.ScaleVariation()
#--> 7882814.17
composed from the signature, run for this page
no extension
ScaleBarAt
(no comment in the source: the name reads as a sentence) scale bar at
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? @@( o1.ScaleBarAt(2, 5) )
#--> [ [ "km", 100 ], [ "pixels", 2.36 ], [ "atlat", 5 ], [ "variation", 7882814.17 ] ]
composed from the signature, run for this page
no extension
DrawNorthArrowOn
NORTH, WHICH IS NOT ALWAYS UP. On most world projections it is, and the arrow is then decoration; on a rotated or oblique one it is not, and a reader has no other way to know. So the arrow is MEASURED -- project a short step due north from the given place and draw where it actually went -- rather than drawn pointing up and hoped over.no extension
SunAt
day and night ------------------------------------------------------- WHERE THE SUN IS OVERHEAD at a moment, as [ :lat, :lon, :declination, :equationOfTime ]. The latitude is the solar declination -- which IS the seasons -- and the longitude is simply where noon is.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? @@( o1.SunAt(2, 5, 2, 2) )
#--> [ [ "lat", 15.02 ], [ "lon", 148.43 ], [ "declination", 15.02 ], [ "equationoftime", 6.20 ] ]
composed from the signature, run for this page
no extension
TerminatorAt
THE LINE BETWEEN DAY AND NIGHT, as lon/lat: every place ninety degrees from the subsolar point, which is where the sun is exactly on the horizon.no extension
TwilightAt
...AND TWILIGHT IS THE SAME CIRCLE, FURTHER OUT: civil twilight ends with the sun 6 degrees below the horizon, nautical at 12 and astronomical at 18 -- so they are the circles at 96, 102 and 108. One routine draws all four because they are one thing.no extension
SolarElevationAt
HOW HIGH THE SUN IS at a place, degrees -- negative is night. It is the terminator asked as a question rather than drawn as a line, and is what SHADES a map rather than outlining it.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.SolarElevationAt(2, 5, 2, 2, 2, 2)
#--> -52.67
composed from the signature, run for this page
no extension
IsDaylightAt
(no comment in the source: the name reads as a sentence) is daylight at
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.IsDaylightAt(2, 5, 2, 2, 2, 2)
#--> 0
composed from the signature, run for this page
no extension
DrawTerminatorOn
THE NIGHT SIDE, drawn. The terminator is a great circle, so on most projections it is a curve that leaves the sheet at one edge and comes back at the other -- which is why it is drawn as a LINE over a shading rather than as a filled polygon: a polygon would have to decide what "inside" means on a projection that cuts it, and would get it wrong at exactly the two solstices.no extension
DrawNightOn
FOUR NESTED CAPS give the gradient a reader sees at dusk: the sun is 6 degrees below the horizon at 84 from the antipode, nautical at 78, astronomical at 72. Drawn outermost first, each translucent, so they ACCUMULATE -- the deepest night is four layers deep and full dark is reached gradually rather than in one step.no extension
DrawTwilightOn
...and the twilight bands with it, each fainter than the last, which is what a day-night map actually looks likeno extension
DrawVectorsRampedOn
An arrow's LENGTH is the natural encoding and it is a poor one at small sizes: a reader compares two short strokes by eye and gets the ordering, not the ratio. Colour gives the ratio. Wolfram's VectorPlot uses both together and that is why its fields read at a glance, so this does too -- and the two agreeing is what makes a long arrow read as fast rather than merely as long.no extension
DrawVectorsOn
(no comment in the source: the name reads as a sentence) draw vectors onno extension
DrawStreamlinesOn
Euler's method is three lines shorter and spirals OUTWARD on a field that rotates -- so a closed circular flow comes back as an opening spiral, which a reader takes for a real divergence rather than for the integrator's own error. RK4 costs four samples a step and holds the circle to a part in ten thousand over three thousand steps.no extension
DrawFlowOn
The stroke then varies with SPEED, because a streamline of constant width says every part of the flow is equally fast, and that is the one thing a streamline cannot otherwise deny.QCSXTZZZIBWU
DrawFlowRampedOn
Colour is the strongest channel there is for a scalar. Width is one of the weakest, and it is spent here anyway -- kept as a SECOND encoding of the same quantity, because the two agreeing is what makes a fast line read as fast rather than merely as orange.QCSXTZZZIBWU
StreamlineFrom
(no comment in the source: the name reads as a sentence) streamline fromno extension
VectorsOf
(no comment in the source: the name reads as a sentence) vectors ofno extension
SpeedField
THE LINES ARE ONE DARK INK, not the ramp. The colour is in the ground now, and a second colour scale on the lines would be two encodings of one quantity fighting for the same eye. The flow's job over a density is to show the SHAPE; the ground shows the magnitude. THE SPEED AT EVERY NODE, sqrt(u^2 + v^2) -- the scalar a stream-density plot shades, exposed so a caller can hand it to a stzGeoField of their own, and so the property that the background IS the magnitude can be checked rather than trusted.no extension
DrawStreamDensityOn
(no comment in the source: the name reads as a sentence) draw stream density onQCSXTZZZIBWU
DrawLegendOn
the legend and the caption ------------------------------------------- THE LEGEND SAYS WHAT EVERY SHADE MEANS, and a class that colours nothing says so: a legend promising a shade the map never shows is the fault DN24's own rules were written to catch, and it is the same fault here.no extension
Caption
how the map was made, and on whose word its borders are where they are. A map with no source says "source not stated" rather than nothing, because silence reads as authority.
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.Caption()
#--> Mercator  |  boundaries: source not stated
composed from the signature, run for this page
no extension
DrawCaptionOn
(no comment in the source: the name reads as a sentence) draw caption onno extension
Findings
The severities follow the house convention: an ERROR is a picture that ARGUES AGAINST ITSELF and a warning ADVISES. A map missing its source is a warning because the picture is still true; a choropleth on a projection that distorts area is an ERROR because the picture is not.no extension
IsOnPaper
does any point of this feature reach the paper at all?no extension
IsSound
(no comment in the source: the name reads as a sentence) is sound
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.IsSound()
#--> 1
composed from the signature, run for this page
no extension
PlaceAt
What a click is over. The projection is inverted to a place on the sphere and the place is asked of the features -- so the answer is right on a globe, on a cut map, and under any rotation, because none of that is special-cased: it is the same invert the guard asserts round-trips on all sixteen projections. [ lon, lat ] under a pixel, or [] off the sphereno extension
FeatureAt
the feature under a pixel, or 0 for the sea, the sky and the margin
composed example
cJ = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"A"},"geometry":{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}}]}'
oF = StzGeoFeaturesFromJson(cJ)
o1 = StzGeoMap(new stzGeoProjection(:mercator), oF)
? o1.FeatureAt(2, 5)
#--> 0
composed from the signature, run for this page
no extension
NameAt
...and what it is called, or "" -- what a tooltip showsno extension
ValueAt
...and its value, or "" where it has noneno extension