summaryrefslogtreecommitdiff
path: root/tex/context
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2021-07-21 20:14:30 +0200
committerContext Git Mirror Bot <phg@phi-gamma.net>2021-07-21 20:14:30 +0200
commit215aeff4092b7483f4ac024d19984a37c381ba52 (patch)
tree09971430ccf95690ea3ab7c6b1bc283316e8fea8 /tex/context
parenta06e8a0d7325ee248138a327e1117139b71aeaba (diff)
downloadcontext-215aeff4092b7483f4ac024d19984a37c381ba52.tar.gz
2021-07-21 19:53:00
Diffstat (limited to 'tex/context')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/mult-fr.mkii1
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/lxml-lpt.lua4
-rw-r--r--tex/context/base/mkiv/page-lin.mkvi4
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin23617 -> 23616 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin248519 -> 248528 bytes
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/context.mkxl2
-rw-r--r--tex/context/base/mkxl/lpdf-tag.lmt50
-rw-r--r--tex/context/base/mkxl/page-lin.mklx12
-rw-r--r--tex/context/base/mkxl/strc-tag.mkxl2
-rw-r--r--tex/context/interface/mkii/keys-fr.xml1
-rw-r--r--tex/context/modules/mkiv/m-compatible.mkiv4
-rw-r--r--tex/context/modules/mkiv/m-mkii.mkiv2
-rw-r--r--tex/context/modules/mkiv/m-obsolete.mkiv2
-rw-r--r--tex/context/modules/mkiv/m-oldfun.mkiv2
-rw-r--r--tex/context/modules/mkiv/m-oldnum.mkiv2
-rw-r--r--tex/context/modules/mkiv/m-units.mkiv2
-rw-r--r--tex/context/modules/mkxl/m-openstreetmap.lmt906
-rw-r--r--tex/context/modules/mkxl/m-openstreetmap.mkxl461
23 files changed, 1437 insertions, 30 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 5f88118e5..ddc6e4c94 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2021.07.16 21:58}
+\newcontextversion{2021.07.21 19:51}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index f82269d66..f51879ef6 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.07.16 21:58}
+\edef\contextversion{2021.07.21 19:51}
%D For those who want to use this:
diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii
index de20eb6f0..0390fcdbc 100644
--- a/tex/context/base/mkii/mult-fr.mkii
+++ b/tex/context/base/mkii/mult-fr.mkii
@@ -1236,6 +1236,7 @@
\setinterfaceconstant{splitoffset}{decalagepartage}
\setinterfaceconstant{spot}{tondirect}
\setinterfaceconstant{stack}{pile}
+\setinterfaceconstant{stacking}{stacking}
\setinterfaceconstant{stackname}{nompile}
\setinterfaceconstant{start}{début}
\setinterfaceconstant{starter}{demarreur}
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index f805e1f8d..668a2bb71 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.07.16 21:58}
+\newcontextversion{2021.07.21 19:51}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 11f827ce2..c49efc796 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.07.16 21:58}
+\edef\contextversion{2021.07.21 19:51}
%D Kind of special:
diff --git a/tex/context/base/mkiv/lxml-lpt.lua b/tex/context/base/mkiv/lxml-lpt.lua
index 9e4b475fb..78a9fca2e 100644
--- a/tex/context/base/mkiv/lxml-lpt.lua
+++ b/tex/context/base/mkiv/lxml-lpt.lua
@@ -635,7 +635,9 @@ local builtin = {
match = "(ll.mi or 1)",
namespace = "ll.ns",
ns = "ll.ns",
-
+ -- new
+ -- attribute = "ll.at",
+ -- at = "ll.at",
}
local lp_builtin = lpeg.utfchartabletopattern(builtin)/builtin * ((spaces * P("(") * spaces * P(")"))/"")
diff --git a/tex/context/base/mkiv/page-lin.mkvi b/tex/context/base/mkiv/page-lin.mkvi
index e355e3e60..3a54d1ef5 100644
--- a/tex/context/base/mkiv/page-lin.mkvi
+++ b/tex/context/base/mkiv/page-lin.mkvi
@@ -352,7 +352,9 @@
\def\page_lines_add_numbers_to_box#box#column#max#nesting%
{\bgroup
- \strc_tags_enable_indeed
+ \ifconditional\c_strc_tags_enabled
+ \strc_tags_enable_indeed
+ \fi
\b_page_lines_number #box\relax
\c_page_lines_column #column\relax
\c_page_lines_last_column#max\relax
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 751c819da..82fa2f6a3 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 0737a3f55..26b23cda0 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 8c029b2e4..70b47d75d 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.07.16 21:58}
+\newcontextversion{2021.07.21 19:51}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index 9b1e70180..67ecc671c 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2021.07.16 21:58}
+\immutable\edef\contextversion{2021.07.21 19:51}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/lpdf-tag.lmt b/tex/context/base/mkxl/lpdf-tag.lmt
index 21f5b246d..8c76ca694 100644
--- a/tex/context/base/mkxl/lpdf-tag.lmt
+++ b/tex/context/base/mkxl/lpdf-tag.lmt
@@ -81,6 +81,8 @@ local parent_ref -- delayed
local root -- delayed
local names = { }
local tree = { }
+local firstintree = false
+local lastintree = false
local elements = { }
local structurestags = structures.tags
@@ -137,9 +139,14 @@ local function finishstructure()
if root and #structure_kids > 0 then
local nums = pdfarray()
local n = 0
- for i=1,#tree do
- n = n + 1 ; nums[n] = i - 1
- n = n + 1 ; nums[n] = pdfreference(pdfflushobject(tree[i]))
+ for i=firstintree,lastintree do
+ local ti = tree[i]
+ if ti then
+ n = n + 1 ; nums[n] = i - 1
+ n = n + 1 ; nums[n] = pdfreference(pdfflushobject(ti))
+ else
+ report_tags("beware: missing page %i in tree", i)
+ end
end
local parenttree = pdfdictionary {
Nums = nums
@@ -191,6 +198,19 @@ local function initializepage()
pagenum = texgetcount("realpageno")
pageref = pdfreference(pdfpagereference(pagenum))
list = pdfarray()
+ -- hm, can be later than 1
+ if not firstintree then
+ if pagenum > 1 then
+ report_tags("beware: first page in tree is %i", pagenum)
+ end
+ firstintree = pagenum
+ lastintree = pagenum
+ end
+ if pagenum > lastintree then
+ lastintree = pagenum
+ else
+ report_tags("beware: page order problem in tree at page %i", pagenum)
+ end
tree[pagenum] = list -- we can flush after done, todo
end
@@ -382,19 +402,19 @@ function nodeinjections.addtags(head)
for n, id in nextnode, head do
if id == glyph_code then
-- maybe also disc
-if getchar(n) ~= 0 then
- local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact
- -- if not at then
- -- range = nil
- -- elseif ...
- if last ~= at then
- range = { at, "glyph", n, n, list } -- attr id start stop list
- ranges[#ranges+1] = range
- last = at
- elseif range then
- range[4] = n -- stop
+ if getchar(n) ~= 0 then
+ local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact
+ -- if not at then
+ -- range = nil
+ -- elseif ...
+ if last ~= at then
+ range = { at, "glyph", n, n, list } -- attr id start stop list
+ ranges[#ranges+1] = range
+ last = at
+ elseif range then
+ range[4] = n -- stop
+ end
end
-end
elseif id == hlist_code or id == vlist_code then
local at = getattr(n,a_image)
if at then
diff --git a/tex/context/base/mkxl/page-lin.mklx b/tex/context/base/mkxl/page-lin.mklx
index 3b3a3d71b..5a1dc2e60 100644
--- a/tex/context/base/mkxl/page-lin.mklx
+++ b/tex/context/base/mkxl/page-lin.mklx
@@ -344,7 +344,9 @@
\def\page_lines_add_numbers_to_box#box#column#max#nesting%
{\bgroup
- \strc_tags_enable_indeed
+ \ifconditional\c_strc_tags_enabled
+ \strc_tags_enable_indeed
+ \fi
\b_page_lines_number #box\relax
\c_page_lines_column #column\relax
\c_page_lines_last_column#max\relax
@@ -466,13 +468,13 @@
\dostoptagged}%
\dostoptagged}
-\setuvalue{\??linenumberinghandler\v!left}%
+\protected\defcsname\??linenumberinghandler\v!left\endcsname
{\page_line_handle_left\p_align\leftmarginwidth\leftmargindistance}
-\setuvalue{\??linenumberinghandler\v!right}%
+\protected\defcsname\??linenumberinghandler\v!right\endcsname
{\page_line_handle_right\p_align\rightmarginwidth\rightmargindistance}
-\setuvalue{\??linenumberinghandler\v!inner}%
+\protected\defcsname\??linenumberinghandler\v!inner\endcsname
{\ifodd\realpageno
\ifx\p_align\v!inner
\page_line_handle_left\v!flushleft\leftmarginwidth\leftmargindistance
@@ -491,7 +493,7 @@
\fi
\fi}
-\setuvalue{\??linenumberinghandler\v!outer}%
+\protected\defcsname\??linenumberinghandler\v!outer\endcsname
{\ifodd\realpageno
\ifx\p_align\v!inner
\page_line_handle_right\v!flushleft\leftmarginwidth\leftmargindistance
diff --git a/tex/context/base/mkxl/strc-tag.mkxl b/tex/context/base/mkxl/strc-tag.mkxl
index 96371b6b5..55f8125f8 100644
--- a/tex/context/base/mkxl/strc-tag.mkxl
+++ b/tex/context/base/mkxl/strc-tag.mkxl
@@ -335,6 +335,8 @@
{\enforced\let\getelementtag \donothing
\enforced\let\setupelementuserproperties\gobbletwooptionals}
+\strc_tags_disable
+
%D The triggers:
\newtoks\everyenableelements
diff --git a/tex/context/interface/mkii/keys-fr.xml b/tex/context/interface/mkii/keys-fr.xml
index 3093727aa..beaf78112 100644
--- a/tex/context/interface/mkii/keys-fr.xml
+++ b/tex/context/interface/mkii/keys-fr.xml
@@ -1242,6 +1242,7 @@
<cd:constant name='splitoffset' value='decalagepartage'/>
<cd:constant name='spot' value='tondirect'/>
<cd:constant name='stack' value='pile'/>
+ <cd:constant name='stacking' value='stacking'/>
<cd:constant name='stackname' value='nompile'/>
<cd:constant name='start' value='début'/>
<cd:constant name='starter' value='demarreur'/>
diff --git a/tex/context/modules/mkiv/m-compatible.mkiv b/tex/context/modules/mkiv/m-compatible.mkiv
index 0e056180a..7e6e733ec 100644
--- a/tex/context/modules/mkiv/m-compatible.mkiv
+++ b/tex/context/modules/mkiv/m-compatible.mkiv
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\ifcase\contextlmtxmode\else\endinput\fi
+
%D I fear that I will not keep up in this file so feel free to contribute to the
%D following. The idea is nto to load this file but more to have some insight in
%D how to control compatibility (to some extent).
@@ -58,6 +60,4 @@
% \input page-cst.mkiv
-
-
\endinput
diff --git a/tex/context/modules/mkiv/m-mkii.mkiv b/tex/context/modules/mkiv/m-mkii.mkiv
index dcfd29d20..4961b7380 100644
--- a/tex/context/modules/mkiv/m-mkii.mkiv
+++ b/tex/context/modules/mkiv/m-mkii.mkiv
@@ -1,5 +1,7 @@
% todo
+\ifcase\contextlmtxmode\else\endinput\fi
+
\unprotect
\writestatus\m!system{loading some mkii compatibility hacks}
diff --git a/tex/context/modules/mkiv/m-obsolete.mkiv b/tex/context/modules/mkiv/m-obsolete.mkiv
index 2d4518181..73fb1c167 100644
--- a/tex/context/modules/mkiv/m-obsolete.mkiv
+++ b/tex/context/modules/mkiv/m-obsolete.mkiv
@@ -1,3 +1,5 @@
+\ifcase\contextlmtxmode\else\endinput\fi
+
\unprotect
\writestatus\m!system{skipping obsolete module}
diff --git a/tex/context/modules/mkiv/m-oldfun.mkiv b/tex/context/modules/mkiv/m-oldfun.mkiv
index f20d7d8e9..9530aa065 100644
--- a/tex/context/modules/mkiv/m-oldfun.mkiv
+++ b/tex/context/modules/mkiv/m-oldfun.mkiv
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\ifcase\contextlmtxmode\else\endinput\fi
+
\unprotect
%D Beware, these macros wil be replaced and at some point this
diff --git a/tex/context/modules/mkiv/m-oldnum.mkiv b/tex/context/modules/mkiv/m-oldnum.mkiv
index 5109cca12..63ac15085 100644
--- a/tex/context/modules/mkiv/m-oldnum.mkiv
+++ b/tex/context/modules/mkiv/m-oldnum.mkiv
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\ifcase\contextlmtxmode\else\endinput\fi
+
% See end for transition to mkiv.
\writestatus{loading}{ConTeXt Support Macros / Numbers}
diff --git a/tex/context/modules/mkiv/m-units.mkiv b/tex/context/modules/mkiv/m-units.mkiv
index 4f25fffc6..02d1b6aa7 100644
--- a/tex/context/modules/mkiv/m-units.mkiv
+++ b/tex/context/modules/mkiv/m-units.mkiv
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+\ifcase\contextlmtxmode\else\endinput\fi
+
%D Best use the built in unit handle!
%D Scientific units can be typeset in math mode pretty well,
diff --git a/tex/context/modules/mkxl/m-openstreetmap.lmt b/tex/context/modules/mkxl/m-openstreetmap.lmt
new file mode 100644
index 000000000..2116ae236
--- /dev/null
+++ b/tex/context/modules/mkxl/m-openstreetmap.lmt
@@ -0,0 +1,906 @@
+if not modules then modules = { } end modules ['m-openstreetmap'] = {
+ version = 1.001,
+ comment = "companion to m-openstreetmap.mkxl",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local sin, cos, floor, ceil = math.sin, math.cos, math.floor, math.ceil
+local formatters = string.formatters
+local concat, tohash, sortedhash, setmetatableindex, insert = table.concat, table.tohash, table.sortedhash, table.setmetatableindex, table.insert
+local xmlcollected, xmlparent, xmlfirst, xmlfilter = xml.collected, xml.parent, xml.first, xml.filter
+local P, S, Cs, lpegmatch = lpeg.P, lpeg.S, lpeg, lpeg.match
+
+local openstreetmap = { }
+moduledata.openstreetmap = openstreetmap
+
+local report = logs.reporter("openstreetmap")
+
+-- At one of the bachotex meetings Mojca and I sat down to render the bachotek camp site
+-- as available in openstreetmap. Of course that was a limited setup and after figuring
+-- out some details it went well. Of course we used metapost.
+--
+-- Years later in 2021 on the mailing list there was some discussion on country outlines
+-- and disappointed by the quality of what was referred to I remembered the openstreetmap
+-- adventure. I found that I could export my hometown from the web page so I started from
+-- that: just stepwise seeing what 'ways' passed and assigning them colors. Just as with
+-- the bachotex drawing.
+--
+-- Then I went searching for what tags actually were available and ran into:
+--
+-- https://github.com/openstreetmap/osm2pgsql/blob/master/docs/lua.md
+--
+-- I'm not sure where the script is used, and there are dead linsk on these pages but some
+-- information can be found in that file so I could combine our findings with these. There
+-- is a whole infrastructure out there with impressive machinery, style sheet generation
+-- etc. but we don't need that here. Also, we don't need to play routes.
+--
+-- Colors are one thing (not too hard with a k/v mapping), but a nest hurdle is to decide
+-- what is a polygon. Actually I found that just checking on something being closed is
+-- rather ok. There are a few extra ones. But we can also use the list in the file mentioned.
+-- We probably need to check it occasionally with the original, although it looks quite
+-- stable.
+
+local polygons = tohash {
+ "abandoned:aeroway", "abandoned:amenity", "abandoned:building",
+ "abandoned:landuse", "abandoned:power", "aeroway", "allotments",
+ "amenity", "area:highway", "craft", "building", "building:part", "club",
+ "golf", "emergency", "harbour", "healthcare", "historic", "landuse",
+ "leisure", "man_made", "military", "natural", "office", "place", "power",
+ "public_transport", "shop", "tourism", "water", "waterway", "wetland",
+
+ -- "bridge",
+}
+
+-- The amenity tag is sort of overloading the main tag so we put it in the main
+-- hash. This might change.
+--
+-- The stacking order is important and we just started with processing the tags
+-- in a certain order. However, in \LUAMETATEX\ we can now use stacking so that
+-- makes for a nice test. At the cost of a bit more metapost code and conversion
+-- time we can use that. Anyway, this is the list we use and it's an adaption
+-- from the bachitex one.
+
+local order = {
+ "landuse",
+ "leisure",
+ "natural",
+ -- "geological",
+
+ "water",
+ "amenity",
+ "building",
+ "barrier",
+ "man_made",
+ "bridge",
+
+ "historic",
+ "military",
+
+ -- "office",
+ -- "craft",
+
+ -- "emergency",
+ -- "healthcare",
+ -- "place",
+ -- "power",
+ -- "shop",
+ -- "sport",
+ -- "telecom",
+
+ -- "publictransport",
+
+ "waterway",
+ "highway",
+ "railway",
+ "aeroway",
+ "aerialway",
+
+ -- "tourism",
+ "boundary", -- overlaps ! not okay for hasselt.osm
+ -- "route",
+}
+
+-- From the mentioned lua file we get the stacking (funny numbers are used):
+
+-- In Hasselt we have a combination, highway should win :
+--
+-- <tag k="bridge" v="yes"/>
+-- <tag k="highway" v="footway"/>
+
+local stacking = {
+ highway = {
+ motorway = 180,
+ trunk = 170,
+ primary = 160,
+ secondary = 150,
+ tertiary = 140,
+ residential = 130,
+ unclassified = 130,
+ road = 130,
+ living_street = 120,
+ pedestrian = 110,
+ raceway = 100,
+ motorway_link = 140,
+ trunk_link = 130,
+ primary_link = 120,
+ secondary_link = 110,
+ tertiary_link = 100,
+ service = 150,
+ track = 110,
+ path = 100,
+ footway = 100,
+ bridleway = 100,
+ cycleway = 100,
+ steps = 190,
+ platform = 190,
+ },
+ railway = {
+ rail = 140,
+ subway = 120,
+ narrow_gauge = 120,
+ light_rail = 120,
+ funicular = 120,
+ preserved = 120,
+ monorail = 120,
+ miniature = 120,
+ turntable = 120,
+ tram = 110,
+ disused = 100,
+ construction = 100,
+ platform = 190,
+ },
+ aeroway = {
+ runway = 160,
+ taxiway = 150,
+ },
+ boundary = {
+ administrative = 0,
+ },
+
+ -- bridge = {
+ -- yes = 103,
+ -- movable = 102,
+ -- viaduct = 103,
+ -- },
+}
+
+setmetatableindex(stacking,function(t,k)
+ local v = setmetatableindex(function(t,k)
+ t[k] = false return false
+ end)
+ t[k] = v
+ return v
+end)
+
+-- reservoir_covered: @ bachotex
+
+local colors = {
+
+ -- these concern details:
+
+ amenity = {
+ arts_centre = true,
+ bar = true,
+ bicycle_parking = true,
+ college = true,
+ courthouse = true,
+ fountain = true,
+ hospital = true,
+ kindergarten = true,
+ marketplace = true,
+ parking = true,
+ parking_space = true,
+ pharmacy = true,
+ place_of_worship = true,
+ police = true,
+ restaurant = true,
+ school = true,
+ shower = true,
+ social_facility = true,
+ toilets = true,
+ townhall = true,
+ university = true,
+ },
+
+ -- these are basic:
+
+ boundary = {
+ aboriginal_lands = true,
+ national_park = true,
+ protected_area = true,
+ administrative = true,
+ },
+ building = {
+ apartments = true,
+ bandstand = true,
+ cathedral = true,
+ civic = true,
+ commercial = true,
+ construction = true, -- no roadtrip
+ garage = true,
+ government = true,
+ hospital = true,
+ house = true,
+ houseboat = true,
+ hut = true,
+ industrial = true,
+ kiosk = true,
+ public = true,
+ residential = true,
+ retail = true,
+ roof = true,
+ school = true,
+ shed = true,
+ townhall = true,
+ yes = true,
+ },
+ emergency = {
+ designated = true,
+ destination = true,
+ no = true,
+ official = true,
+ yes = true,
+ },
+ man_made = {
+ breakwater = true,
+ bridge = true,
+ instrument = true,
+ pier = true,
+ quay = true,
+ tower = true,
+ windmill = true,
+ cutline = true,
+ embankment = true,
+ groyne = true,
+ pipeline = true,
+ },
+ natural = {
+ arete = true,
+ cliff = true,
+ earth_bank = true,
+ ridge = true,
+ sand = true,
+ scrub = true,
+ tree_row = true,
+ water = true,
+ wetland = true,
+ wood = true,
+ },
+ barrier = {
+ chain = true,
+ city_wall = true,
+ fence = true,
+ gate = true,
+ guard_rail = true,
+ hedge = true,
+ retaining_wall = true,
+ wall = true,
+ yes = true,
+ },
+ leisure = {
+ garden = true,
+ ice_rink = true,
+ marina = true,
+ park = true,
+ pitch = true,
+ playground = true,
+ slipway = true,
+ sports_centre = true,
+ track = true,
+ beach = true,
+ },
+ boat = {
+ yes = true,
+ },
+ landuse = {
+ allotments = true,
+ cemetery = true,
+ commercial = true,
+ construction = true,
+ forest = true,
+ grass = true,
+ industrial = true,
+ meadow = true,
+ residential = true,
+ static_building = true,
+ village_green = true,
+ },
+ ["bridge:support"] = {
+ pier = true,
+ },
+ golf = { -- funny, this category
+ cartpath = true,
+ hole = true,
+ path = true,
+ },
+ area = {
+ yes = true,
+ },
+ bridge = {
+ yes = true,
+ movable = true,
+ viaduct = true,
+ },
+ agricultural = {
+ yes = true,
+ no = true,
+ },
+ historic = {
+ citywalls = true,
+ },
+ tourism = {
+ yes = true,
+ },
+ power = {
+ cable = true,
+ line = true,
+ minor_line = true,
+ },
+ junction = {
+ yes = true,
+ },
+ water = {
+ river = true,
+ basin = true,
+ },
+
+ -- these indicate routes:
+
+ highway = {
+ corridor = true,
+ bridleway = true,
+ cycleway = true,
+ footway = true,
+ living_street = true,
+ motorway = true,
+ motorway_link = true,
+ path = true,
+ pedestrian = true,
+ platform = true,
+ primary = true,
+ primary_link = true,
+ raceway = true,
+ residential = true,
+ rest_area = true,
+ road = true,
+ -- secondary = true,
+ secondary_link = true,
+ service = true,
+ services = true,
+ steps = true,
+ tertiary = true,
+ tertiary_link = true,
+ track = true,
+ trunk = true,
+ trunk_link = true,
+ unclassified = true,
+ },
+ waterway = {
+ canal = true,
+ derelict_canal = true,
+ ditch = true,
+ drain = true,
+ river = true,
+ stream = true,
+ tidal_channel = true,
+ wadi = true,
+ weir = true,
+ },
+ railway = {
+ construction = true,
+ disused = true,
+ funicular = true,
+ light_rail = true,
+ miniature = true,
+ monorail = true,
+ narrow_gauge = true,
+ platform = true,
+ preserved = true,
+ rail = true,
+ station = true,
+ subway = true,
+ tram = true,
+ turntable = true,
+ },
+
+ aeroway = {
+ runway = true,
+ taxiway = true,
+ },
+ aerialway = {
+ station = true,
+ },
+}
+
+-- We use this 'inside' knowledge encoded in the mentioned script to avoid bad fills
+-- (for instance polygons can be unconnected and unordered). We define the table a bit
+-- different.
+
+local forcedlines = {
+ golf = { "cartpath", "hole", "path" },
+ emergency = { "designated", "destination", "no", "official", "yes" },
+ historic = { "citywalls" },
+ leisure = { "track", "slipway" },
+ man_made = { "breakwater", "cutline", "embankment", "groyne", "pipeline" },
+ natural = { "cliff", "earth_bank", "tree_row", "ridge", "arete" },
+ power = { "cable", "line", "minor_line" },
+ tourism = { "yes"},
+ waterway = { "canal", "derelict_canal", "ditch", "drain", "river", "stream", "tidal_channel", "wadi", "weir" },
+}
+
+do
+
+ local function never(t,k) t[k] = false return false end
+
+ for k, v in next, forcedlines do
+ forcedlines[k] = setmetatableindex(tohash(v),never)
+ end
+
+ setmetatableindex(forcedlines,function(t,k)
+ local v = setmetatableindex(never)
+ t[k] = v
+ return v
+ end)
+
+end
+
+-- For fast checking we apply the usual context tricks:
+
+
+for k, v in next, colors do
+ for kk, vv in next, v do
+ v[kk] = "osm:" .. k .. ":" .. kk
+ end
+end
+
+-- We draw and fill but sometimes we do both:
+
+local lines = {
+ amenity = true,
+ building = true,
+ man_made = true,
+ boat = true,
+}
+
+-- When checking labels for a while I had a blacklist of tags (keys) but
+-- dropped that when most was done. So, we're now ready for the real deal:
+
+-- this only works for positive numbers
+
+local f_f_degree_to_str = formatters["%d°%d’%.0f”"]
+
+local function f_degree_to_str(num)
+ local deg = floor(num)
+ num = (num - deg) * 60
+ local min = floor(num)
+ num = (num - min) * 60
+ local sec = num
+ return f_f_degree_to_str(deg,min,sec)
+end
+
+-- local f_pattern = formatters["/osm/(way|relation)[@visible='true']/tag[@k='%s']"]
+local f_pattern = formatters["/osm/(way|relation)[@visible!='false']/tag[@k='%s']"]
+local f_way = formatters["/osm/way[@id='%s']"]
+local f_relation = formatters["/osm/relation[@id='%s']"]
+
+-- We could reuse paths and concat 0,n in the call but when testing it the gain was
+-- not much so I went for readability.
+
+local f_draw = formatters['D %--t W "%s";']
+local f_fill = formatters['F %--t--C W "%s";']
+local f_both = formatters['P := %--t--C; F P W "%s"; D P W "white" L 2;']
+local f_draw_s = formatters['D %--t W "%s" L %s;']
+local f_fill_s = formatters['F %--t--C W "%s" L %s;']
+local f_both_s = formatters['P := %--t--C; F P W "%s"; D P W "white" L %s;']
+
+local f_nodraw = formatters['ND %--t;']
+local f_nofill = formatters['NF %--t--C;']
+local f_nodraw_s = formatters['ND %--t;']
+local f_nofill_s = formatters['NF %--t--C;']
+
+local f_background = formatters['F %--t -- C W "osm:background";']
+local f_bounds = formatters['setbounds currentpicture to %--t--C ;']
+
+-- For now no labels are printed, also because that's now what we use this for. At
+-- some point I will provide some hooks to put text at coordinates.
+
+-- local f_draw_p = formatters["path p ; p := %--t ; D p W %s;"]
+-- local f_fill_p = formatters["path p ; p := %--t -- C ; F p W %s;"]
+-- local f_textext = formatters['draw (textext("\\bf %s") scaled 0.35) shifted center p withcolor white;']
+
+-- Grids were also part of the original code, so I kept that. It's done a bit more
+-- efficient by using a single path.
+
+local f_draw_grid_b = formatters['nodraw %--t L 100;']
+local f_draw_grid_e = formatters['dodraw origin dashed %s withcolor "osm:grid" withpen pencircle scaled %N L 100;']
+local f_label_lat = formatters['label.urt((textext("\\infofont\\strut %s")), %s shifted (3,0)) withcolor white L 100;']
+local f_label_lon = formatters['label.top((textext("\\infofont\\strut %s")), %s shifted (0,3)) withcolor white L 100;']
+
+local beginmp = [[
+ begingroup ;
+ pickup pencircle scaled 1 ;
+ save P ; path P ;
+ save D ; let D = draw ;
+ save F ; let F = fill ;
+ save C ; let C = cycle ;
+ save W ; let W = withcolor ;
+ save L ; let L = withstacking ;
+ save ND ; let ND = nodraw ;
+ save DD ; let DD = dodraw ;
+ save NF ; let NF = nofill ;
+ save DF ; let DF = dofill ;
+]]
+
+local endmp = [[
+ endgroup;
+]]
+
+local p_strip = lpeg.Cs( (
+ (
+ ( P("version") + P("changeset") + P("timestamp") + P("user") + P("uid") )
+ * P('="') * (1-P('"'))^0 * P('"')
+ ) / ""
+ + P(">") * (S("\n\r\t\f ")^1 / "") * P("<")
+ + P('visible="true"') / ""
+ + P(1)
+)^1 )
+
+function openstreetmap.convert(specification)
+
+ local starttime = os.clock()
+ local filename = specification.filename
+
+ if not io.exists(filename) then
+ return
+ end
+
+ report("processing file %a",filename)
+
+ -- we can consider stripping crap first
+
+ -- local root = xml.load(filename)
+
+ local root = io.loaddata(filename)
+ local olds = #root
+ root = lpegmatch(p_strip,root)
+ local news = #root
+
+ report("original size %i bytes, stripped down to %i bytes",olds,news)
+
+ root = xml.convert(root)
+
+ if root.error then
+ report("error in xml",olds,news)
+ return
+ else
+ report("xml data loaded")
+ end
+
+ local bounds = xmlfirst(root,"/osm/bounds")
+ if not bounds then
+ return
+ end
+
+ local usercolors = specification.used
+ local usedcolors = table.copy(colors)
+
+ if usercolors then
+ for k, v in next, usercolors do
+ local u = usedcolors[k]
+ if not u then
+ -- error
+ elseif v == false then
+ usedcolors[k] = false
+ -- for k in next, u do
+ -- u[k] = false
+ -- end
+ elseif type(v) == "string" then
+ for k in next, u do
+ u[k] = v
+ end
+ elseif type(v) == "table" then
+ for kk, vv in next, v do
+ if vv == false then
+ u[kk] = false
+ elseif type(vv) == "string" then
+ u[kk] = vv
+ end
+ end
+ end
+ end
+ end
+
+ -- inspect(usedcolors)
+
+ local minlat = bounds.at.minlat
+ local minlon = bounds.at.minlon
+ local maxlat = bounds.at.maxlat
+ local maxlon = bounds.at.maxlon
+ local midlat = 0.5 * (minlat + maxlat)
+ local deg_to_rad = math.pi / 180.0
+ local scale = 3600 -- vertical scale: 1" = 1cm
+
+ local function f_pair(lon, lat)
+ return formatters("(%.3Ncm,%.3Ncm)", (lon - minlon) * scale * cos(midlat * deg_to_rad), (lat-minlat) * scale)
+ end
+
+ local rendering = table.tohash(order)
+ local coordinates = { }
+ local ways = { }
+ local result = { }
+ local r = 0
+ local done = { }
+ local missing = false -- setmetatableindex("table")
+ local layers = { }
+ local areas = { }
+
+ for c in xmlcollected(root,"/osm/node") do
+ local a = c.at
+ coordinates[a.id] = a
+ end
+
+ for c in xmlcollected(root,"/osm/way") do
+ ways[c.at.id] = c
+ end
+
+ for c in xml.collected(root,"tag[@k='area']") do
+ areas[c] = c.at.v
+ end
+
+ for c in xml.collected(root,"tag[@k='layer']") do
+ layers[c] = c.at.v
+ end
+
+ -- Collecting is more a private option. It doesn't save much on the output
+ -- but looks better with transparency, which makes no sense using anyway.
+
+ local collected = specification.collect and setmetatableindex(function(t,k)
+ local v = setmetatableindex(function(t,k)
+ local v = {
+ draw = setmetatableindex("table"),
+ fill = setmetatableindex("table"),
+ }
+ t[k] = v
+ return v
+ end)
+ t[k] = v
+ return v
+ end) or false
+
+ local function drawshapes(what,order)
+
+ -- see bachotex rendering for an example
+ -- also layer and polygon
+
+ function xml.expressions.osm(k)
+ return usedcolors[k]
+ end
+
+ local function getcolor(r)
+ local t = xmlfirst(r,"/tag[osm(@k)]")
+ if t then
+ local at = t.at
+ local v = at.v
+ if v ~= "no" then
+ local k = at.k
+ local col = usedcolors[k][v]
+ -- we need an example: if layers[r] then print(layers[r]) end
+ if col then
+ -- todo : trace colors and stacking
+ return k, col, lines[k], stacking[k][v], forcedlines[k][v]
+ elseif missing then
+ missing[k][v] = (missing[k][v] or 0) + 1
+ end
+ end
+ end
+ end
+
+ local function addpath(r, p, n)
+ -- if done[r] then
+ -- print("AGAIN")
+ -- else
+ for c in xmlcollected(r,"/nd") do
+ local coordinate = coordinates[c.at.ref]
+ if coordinate then
+ n = n + 1 p[n] = f_pair(coordinate.lon, coordinate.lat)
+ end
+ end
+ -- done[r] = true
+ -- end
+ return p, n
+ end
+
+ local checkpath = collected and
+
+ function(parent,p,n)
+ local what, color, both, stacking, forced = getcolor(parent)
+ if what and rendering[what] then
+ local where = collected[stacking or order]
+ if not polygons[what] or forced or areas[parent] == "no" then
+ insert(where[color] .draw, f_nodraw(p))
+ elseif both then
+ insert(where[color] .fill, f_nofill(p))
+ insert(where["white"].draw, f_nodraw(p))
+ else
+ insert(where[color] .fill, f_nofill(p))
+ end
+ end
+ end
+
+ or
+
+ function(parent,p,n)
+ local what, color, both, stacking, forced = getcolor(parent)
+ if what and rendering[what] then
+ r = r + 1
+ -- if not stacking then
+ -- stacking = order
+ -- end
+ if not polygons[what] or forced or areas[parent] == "no" then
+ result[r] = stacking and f_draw_s(p,color,stacking) or f_draw(p,color)
+ elseif both then
+ result[r] = stacking and f_both_s(p,color,stacking) or f_both(p,color)
+ else
+ result[r] = stacking and f_fill_s(p,color,stacking) or f_fill(p,color)
+ end
+ end
+ end
+
+ -- There are ways and relations. Relations can have members that poitn to
+ -- ways but also relations. My impression is that we can stick to way members
+ -- but I'll deal with that when needed.
+
+ for c in xmlcollected(root,f_pattern(what)) do
+ local parent = xmlparent(c)
+ local tag = parent.tg
+ if tag == "way" then
+ local p, n = addpath(parent, { }, 0)
+ if n > 1 then
+ checkpath(parent,p,n)
+ end
+ elseif tag == "relation" then
+ if xmlfilter(parent,"xml://tag[@k='type' and (@v='multipolygon' or @v='boundary' or @v='route')]") then
+ local what, color, both, stacking, forced = getcolor(parent)
+ if rendering[what] then
+ local p, n = { }, 0
+ for m in xmlcollected(parent,"/member[(@type='way') and (@role='outer')]") do
+ -- local f = xmlfirst(root,f_way(m.at.ref))
+ local f = ways[m.at.ref]
+ if f then
+ p, n = addpath(f,p,n)
+ end
+ end
+ if n > 1 then
+ checkpath(parent,p,n)
+ end
+ end
+ else
+ for m in xmlcollected(parent,"/member[@type='way']") do
+ -- local f = xmlfirst(root,f_way(m.at.ref))
+ local f = ways[m.at.ref]
+ if f then
+ local p, n = addpath(f, { }, 0)
+ if n > 1 then
+ checkpath(parent,p,n)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ end
+
+ -- As with the other latitude and longitude mapping calculations the next magick
+ -- comes from Mojca.
+
+ local function drawgrid()
+ local lat0 = ceil (3600*minlat)
+ local lat1 = floor(3600*maxlat)
+ local pen = tonumber(specification.griddot) or 1.5
+ local lat
+ local labels = { }
+ for i=lat0,lat1 do
+ lat = i/3600
+ local p = {
+ f_pair(minlon,lat),
+ f_pair(maxlon,lat),
+ }
+ r = r + 1 result[r] = f_draw_grid_b(p)
+ if i ~= lat0 and i ~= lat1 then
+ labels[#labels+1] = f_label_lat(f_degree_to_str(lat),p[1])
+ end
+ end
+
+ local lon0 = ceil (1800*minlon)*2
+ local lon1 = floor(1800*maxlon)*2
+ local lon
+ for i=lon0,lon1,2 do
+ lon=i/3600
+ local p = {
+ f_pair(lon, minlat),
+ f_pair(lon, maxlat),
+ }
+ r = r + 1 result[r] = f_draw_grid_b(p)
+ if i ~= lon0 and i ~= lon1 then
+ labels[#labels+1] = f_label_lon(f_degree_to_str(lon),p[1])
+ end
+ end
+ r = r + 1 result[r] = f_draw_grid_e("withdots", pen)
+ r = r + 1 result[r] = concat(labels)
+ end
+
+ -- We add a background first and clip later. Beware: There can be substantial bits
+ -- outside the clip path (like rivers) but because paths are not that detailed we
+ -- don't wast time on building a cycle. We could check if points are ouside the
+ -- boundingbox and then use the metapost buildpath macro .. some day.
+
+ local boundary = {
+ f_pair(minlon,minlat),
+ f_pair(maxlon,minlat),
+ f_pair(maxlon,maxlat),
+ f_pair(minlon,maxlat),
+ }
+
+ r = r + 1 result[r] = beginmp
+ r = r + 1 result[r] = f_background(boundary)
+
+ -- r = r + 1 result[r] = "drawoptions (withtransparency (1,.5)) ;"
+
+ -- use stacking instead
+
+ for i=1,#order do
+ local o = order[i]
+ if usedcolors[o] then
+ drawshapes(o,i)
+ end
+ end
+
+ if specification.grid == "dots" then
+ drawgrid()
+ end
+
+ if collected then
+
+ for stacking, colors in sortedhash(collected) do
+ for color, bunch in next, colors do
+ local draw = bunch.draw
+ local fill = bunch.fill
+ if fill and #fill > 0 then
+ r = r + 1 result[r] = "draw image ("
+ r = r + 1 result[r] = concat(fill)
+ r = r + 1 result[r] = 'DF origin--cycle;'
+ r = r + 1 result[r] = formatters[') W "%s" L %s;'](color,stacking) ;
+ end
+ if draw and #draw > 0 then
+ r = r + 1 result[r] = "draw image ("
+ r = r + 1 result[r] = concat(draw)
+ r = r + 1 result[r] = 'DD origin;'
+ r = r + 1 result[r] = formatters[') W "%s" L %s;'](color,stacking+1) ;
+ end
+ end
+ end
+
+ end
+
+ r = r + 1 result[r] = f_bounds(boundary)
+ r = r + 1 result[r] = endmp
+
+ if missing then
+ inspect(missing)
+ end
+
+ result = concat(result)
+
+ report("%s characters metapost code, preprocessing time %0.3f seconds",#result,os.clock()-starttime)
+
+ return result
+
+end
+
+function mp.lmt_do_openstreetmap()
+ local specification = metapost.getparameterset("openstreetmap")
+ return openstreetmap.convert(specification)
+end
diff --git a/tex/context/modules/mkxl/m-openstreetmap.mkxl b/tex/context/modules/mkxl/m-openstreetmap.mkxl
new file mode 100644
index 000000000..677a5a04d
--- /dev/null
+++ b/tex/context/modules/mkxl/m-openstreetmap.mkxl
@@ -0,0 +1,461 @@
+%D \module
+%D [ file=m-database,
+%D version=2020.07.18,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Rendering Openstreetmap,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is a follow up on something that Mojca and I did at at bachotex
+%D meeting. Some attendants had made up that map during a few years. The
+%D \CONTEXT\ group donated a map that could be mounted outside drawn by
+%D Duane and after that we decided to see if we could keep up by rendering
+%D the openstreetmap variant with \METAPOST.
+%D
+%D There are some comments in the \LUA\ file and that one might evolve over
+%D time as there is some trial and error involved. The \typ {osm} file is
+%D read in, stripped a bit, the \XML\ is analyzed and \METAPOST\ code is
+%D generated. The level of detail can be influenced.
+
+% This will change ... users are invited to come with variants.
+
+\definecolor [osm:special] [s=.25]
+
+\definecolor [osm:building:special] [r=.75]
+\definecolor [osm:building] [r=.50]
+
+\definecolor [osm:parking] [s=.25]
+\definecolor [osm:bridge] [s=.50]
+\definecolor [osm:quay] [s=.25]
+\definecolor [osm:barrier] [s=.25]
+\definecolor [osm:industrial] [s=.70]
+\definecolor [osm:residential] [s=.75]
+\definecolor [osm:cemetery] [s=.50]
+
+\definecolor [osm:boat] [b=.25]
+
+\definecolor [osm:water] [b=.75]
+\definecolor [osm:waterway] [r=.75,g=.75]
+
+\definecolor [osm:wetland] [g=.25]
+\definecolor [osm:grass] [g=.50]
+\definecolor [osm:park] [g=.60]
+\definecolor [osm:forest] [g=.75]
+
+\definecolor [osm:sand] [y=.75]
+
+\definecolor [osm:footway] [b=.3]
+\definecolor [osm:cycleway] [b=.5]
+\definecolor [osm:path] [b=.7]
+\definecolor [osm:track] [s=.4]
+
+\definecolor [osm:bridge] [s=.25]
+\definecolor [osm:bridge:special] [s=.50]
+
+\definecolor [osm:unknown] [s=0]
+
+\definecolor [osm:background] [s=.8]
+\definecolor [osm:grid] [s=1]
+
+% We can define them global, in which case we can check for actually
+% used colors.
+
+\definecolor[osm:aerialway:station] [osm:unknown]
+
+\definecolor[osm:aeroway:runway] [osm:unknown]
+\definecolor[osm:aeroway:taxiway] [osm:unknown]
+
+\definecolor[osm:agricultural:no] [osm:unknown]
+\definecolor[osm:agricultural:yes] [osm:unknown]
+
+\definecolor[osm:amenity:arts_centre] [osm:building:special]
+\definecolor[osm:amenity:bar] [osm:building:special]
+\definecolor[osm:amenity:bicycle_parking] [osm:parking]
+\definecolor[osm:amenity:college] [osm:building:special]
+\definecolor[osm:amenity:courthouse] [osm:building:special]
+\definecolor[osm:amenity:fountain] [osm:building:special]
+\definecolor[osm:amenity:hospital] [osm:building:special]
+\definecolor[osm:amenity:kindergarten] [osm:building:special]
+\definecolor[osm:amenity:marketplace] [osm:parking]
+\definecolor[osm:amenity:parking] [osm:parking]
+\definecolor[osm:amenity:parking_space] [osm:parking]
+\definecolor[osm:amenity:pharmacy] [osm:building:special]
+\definecolor[osm:amenity:place_of_worship] [osm:building:special]
+\definecolor[osm:amenity:police] [osm:building:special]
+\definecolor[osm:amenity:restaurant] [osm:building:special]
+\definecolor[osm:amenity:school] [osm:building:special]
+\definecolor[osm:amenity:shower] [osm:building:special]
+\definecolor[osm:amenity:social_facility] [osm:building:special]
+\definecolor[osm:amenity:toilets] [osm:building:special]
+\definecolor[osm:amenity:townhall] [osm:building:special]
+\definecolor[osm:amenity:university] [osm:building:special]
+
+\definecolor[osm:area:yes] [osm:unknown]
+
+\definecolor[osm:barrier:chain] [osm:barrier]
+\definecolor[osm:barrier:city_wall] [osm:barrier]
+\definecolor[osm:barrier:fence] [osm:barrier]
+\definecolor[osm:barrier:gate] [osm:barrier]
+\definecolor[osm:barrier:guard_rail] [osm:barrier]
+\definecolor[osm:barrier:hedge] [osm:barrier]
+\definecolor[osm:barrier:retaining_wall] [osm:barrier]
+\definecolor[osm:barrier:wall] [osm:barrier]
+\definecolor[osm:barrier:yes] [osm:barrier]
+
+\definecolor[osm:boat:yes] [osm:boat]
+
+\definecolor[osm:boundary:aboriginal_lands] [osm:unknown]
+\definecolor[osm:boundary:administrative] [osm:unknown]
+\definecolor[osm:boundary:national_park] [osm:unknown]
+\definecolor[osm:boundary:protected_area] [osm:unknown]
+
+\definecolor[osm:bridge:movable] [osm:bridge:special]
+\definecolor[osm:bridge:viaduct] [osm:bridge]
+\definecolor[osm:bridge:yes] [osm:footway]
+
+\definecolor[osm:bridge:support:pier] [osm:special]
+
+\definecolor[osm:building:apartments] [osm:building]
+\definecolor[osm:building:bandstand] [osm:building:special]
+\definecolor[osm:building:cathedral] [osm:building]
+\definecolor[osm:building:civic] [osm:building]
+\definecolor[osm:building:commercial] [osm:building:special]
+\definecolor[osm:building:construction] [osm:building:special]
+\definecolor[osm:building:garage] [osm:building]
+\definecolor[osm:building:government] [osm:building]
+\definecolor[osm:building:hospital] [osm:building]
+\definecolor[osm:building:house] [osm:building]
+\definecolor[osm:building:houseboat] [osm:boat]
+\definecolor[osm:building:hut] [osm:building]
+\definecolor[osm:building:industrial] [osm:building:special]
+\definecolor[osm:building:kiosk] [osm:building:special]
+\definecolor[osm:building:public] [osm:building]
+\definecolor[osm:building:residential] [osm:building]
+\definecolor[osm:building:retail] [osm:building:special]
+\definecolor[osm:building:roof] [osm:building]
+\definecolor[osm:building:school] [osm:building:special]
+\definecolor[osm:building:shed] [osm:building]
+\definecolor[osm:building:townhall] [osm:building]
+\definecolor[osm:building:yes] [osm:building]
+
+\definecolor[osm:emergency:designated] [osm:unknown]
+\definecolor[osm:emergency:destination] [osm:unknown]
+\definecolor[osm:emergency:no] [osm:unknown]
+\definecolor[osm:emergency:official] [osm:unknown]
+\definecolor[osm:emergency:yes] [osm:unknown]
+
+\definecolor[osm:golf:cartpath] [osm:unknown]
+\definecolor[osm:golf:hole] [osm:unknown]
+\definecolor[osm:golf:path] [osm:unknown]
+
+\definecolor[osm:highway:bridleway] [osm:unknown]
+\definecolor[osm:highway:corridor] [osm:track]
+\definecolor[osm:highway:cycleway] [osm:cycleway]
+\definecolor[osm:highway:footway] [osm:footway]
+\definecolor[osm:highway:living_street] [osm:track]
+\definecolor[osm:highway:motorway] [osm:unknown]
+\definecolor[osm:highway:motorway_link] [osm:unknown]
+\definecolor[osm:highway:path] [osm:path]
+\definecolor[osm:highway:pedestrian] [osm:track]
+\definecolor[osm:highway:platform] [osm:unknown]
+\definecolor[osm:highway:primary] [osm:track]
+\definecolor[osm:highway:primary_link] [osm:unknown]
+\definecolor[osm:highway:raceway] [osm:unknown]
+\definecolor[osm:highway:residential] [osm:track]
+\definecolor[osm:highway:rest_area] [osm:unknown]
+\definecolor[osm:highway:road] [osm:unknown]
+\definecolor[osm:highway:secondary_link] [osm:unknown]
+\definecolor[osm:highway:service] [osm:track]
+\definecolor[osm:highway:services] [osm:unknown]
+\definecolor[osm:highway:steps] [osm:track]
+\definecolor[osm:highway:tertiary] [osm:track]
+\definecolor[osm:highway:tertiary_link] [osm:unknown]
+\definecolor[osm:highway:track] [osm:track]
+\definecolor[osm:highway:trunk] [osm:unknown]
+\definecolor[osm:highway:trunk_link] [osm:unknown]
+\definecolor[osm:highway:unclassified] [osm:track]
+
+\definecolor[osm:historic:citywalls] [osm:unknown]
+
+\definecolor[osm:junction:yes] [osm:unknown]
+
+\definecolor[osm:landuse:allotments] [osm:grass]
+\definecolor[osm:landuse:cemetery] [osm:cemetery]
+\definecolor[osm:landuse:commercial] [osm:industrial]
+\definecolor[osm:landuse:construction] [osm:industrial]
+\definecolor[osm:landuse:forest] [osm:forest]
+\definecolor[osm:landuse:grass] [osm:grass]
+\definecolor[osm:landuse:industrial] [osm:industrial]
+\definecolor[osm:landuse:meadow] [osm:grass]
+\definecolor[osm:landuse:residential] [osm:residential]
+\definecolor[osm:landuse:static_building] [osm:special]
+\definecolor[osm:landuse:village_green] [osm:forest]
+
+\definecolor[osm:leisure:beach] [osm:sand]
+\definecolor[osm:leisure:garden] [osm:park]
+\definecolor[osm:leisure:ice_rink] [osm:water]
+\definecolor[osm:leisure:marina] [osm:quay]
+\definecolor[osm:leisure:park] [osm:park]
+\definecolor[osm:leisure:pitch] [osm:special]
+\definecolor[osm:leisure:playground] [osm:special]
+\definecolor[osm:leisure:slipway] [osm:unknown]
+\definecolor[osm:leisure:sports_centre] [osm:special]
+\definecolor[osm:leisure:track] [osm:track]
+
+\definecolor[osm:man_made:breakwater] [osm:water]
+\definecolor[osm:man_made:bridge] [osm:bridge]
+\definecolor[osm:man_made:cutline] [osm:unknown]
+\definecolor[osm:man_made:embankment] [osm:unknown]
+\definecolor[osm:man_made:groyne] [osm:unknown]
+\definecolor[osm:man_made:instrument] [osm:special]
+\definecolor[osm:man_made:pier] [osm:quay]
+\definecolor[osm:man_made:pipeline] [osm:unknown]
+\definecolor[osm:man_made:quay] [osm:quay]
+\definecolor[osm:man_made:tower] [osm:special]
+\definecolor[osm:man_made:windmill] [osm:special]
+
+\definecolor[osm:natural:arete] [osm:unknown]
+\definecolor[osm:natural:cliff] [osm:unknown]
+\definecolor[osm:natural:earth_bank] [osm:unknown]
+\definecolor[osm:natural:ridge] [osm:unknown]
+\definecolor[osm:natural:sand] [osm:sand]
+\definecolor[osm:natural:scrub] [osm:forest]
+\definecolor[osm:natural:tree_row] [osm:forest]
+\definecolor[osm:natural:water] [osm:water]
+\definecolor[osm:natural:wetland] [osm:wetland]
+\definecolor[osm:natural:wood] [osm:forest]
+
+\definecolor[osm:power:cable] [osm:unknown]
+\definecolor[osm:power:line] [osm:unknown]
+\definecolor[osm:power:minor_line] [osm:unknown]
+
+\definecolor[osm:railway:construction] [osm:unknown]
+\definecolor[osm:railway:disused] [osm:unknown]
+\definecolor[osm:railway:funicular] [osm:unknown]
+\definecolor[osm:railway:light_rail] [osm:unknown]
+\definecolor[osm:railway:miniature] [osm:unknown]
+\definecolor[osm:railway:monorail] [osm:unknown]
+\definecolor[osm:railway:narrow_gauge] [osm:unknown]
+\definecolor[osm:railway:platform] [osm:unknown]
+\definecolor[osm:railway:preserved] [osm:unknown]
+\definecolor[osm:railway:rail] [osm:unknown]
+\definecolor[osm:railway:subway] [osm:unknown]
+\definecolor[osm:railway:tram] [osm:unknown]
+\definecolor[osm:railway:turntable] [osm:unknown]
+
+\definecolor[osm:tourism:yes] [osm:unknown]
+
+\definecolor[osm:water:basin] [osm:water]
+\definecolor[osm:water:river] [osm:water]
+
+\definecolor[osm:waterway:canal] [osm:waterway]
+\definecolor[osm:waterway:derelict_canal] [osm:waterway]
+\definecolor[osm:waterway:ditch] [osm:waterway]
+\definecolor[osm:waterway:drain] [osm:waterway]
+\definecolor[osm:waterway:river] [osm:waterway]
+\definecolor[osm:waterway:stream] [osm:waterway]
+\definecolor[osm:waterway:tidal_channel] [osm:waterway]
+\definecolor[osm:waterway:wadi] [osm:waterway]
+\definecolor[osm:waterway:weir] [osm:waterway]
+
+\registerctxluafile{m-openstreetmap}{autosuffix}
+
+\startMPdefinitions
+
+ presetparameters "openstreetmap" [
+ filename = "test.osm",
+ % grid = "dots",
+ griddot = 1.5,
+ ] ;
+
+ def lmt_openstreetmap = applyparameters "openstreetmap" "lmt_do_openstreetmap" enddef ;
+
+ vardef lmt_do_openstreetmap =
+ image (
+ lua.mp.lmt_do_openstreetmap() ;
+ )
+ enddef ;
+
+\stopMPdefinitions
+
+\continueifinputfile{m-openstreetmap.mkxl}
+
+\startMPpage
+ draw lmt_openstreetmap [
+ filename = "hasselt.osm"
+ used = [
+ boundary = false,
+ ],
+ ] ;
+\stopMPpage
+
+% \startMPpage
+% draw lmt_openstreetmap [
+% filename = "e:/tmp/hulshorst.osm"
+% used = [
+% boundary = false,
+% ],
+% ] ;
+% \stopMPpage
+
+% \startMPpage
+% draw lmt_openstreetmap [
+% filename = "hasselt.osm"
+% used = [
+% boundary = false,
+% emergency = false,
+% boat = false,
+% golf = false,
+% area = false,
+% agricultural = false,
+% historic = false,
+% tourism = false,
+% power = false,
+% junction = false,
+% water = false,
+% highway = false,
+% waterway = false,
+% railway = false,
+% aeroway = false,
+% aerialway = false,
+% ]
+% ] ;
+% \stopMPpage
+
+% \startMPpage
+% draw lmt_openstreetmap [
+% filename = "hasselt.osm"
+% used = [
+% amenity = false,
+% boundary = false,
+% building = false,
+% emergency = false,
+% man_made = false,
+% natural = "magenta",
+% barrier = false,
+% leisure = "cyan",
+% bridge = false,
+% boat = false,
+% landuse = "green",
+% golf = false,
+% area = false,
+% bridge = false,
+% agricultural = false,
+% historic = false,
+% tourism = false,
+% power = false,
+% junction = false,
+% water = false,
+% highway = false,
+% waterway = false,
+% railway = false,
+% aeroway = false,
+% aerialway = false,
+% ]
+% ] ;
+% \stopMPpage
+
+% \startMPpage
+% draw lmt_openstreetmap [
+% filename = "hasselt-large.osm"
+% grid = "dots",
+% % collect = true,
+% ] ;
+% \stopMPpage
+
+% \startMPpage
+% draw lmt_openstreetmap [
+% filename = "e:/tmp/map.osm"
+% ] ;
+% \stopMPpage
+
+% \startMPpage
+% draw lmt_openstreetmap [
+% filename = "e:/tmp/map-x.osm"
+% grid = "dots",
+% griddot = 1,
+% ] ;
+% \stopMPpage
+
+% \startMPpage
+% draw lmt_openstreetmap [
+% filename = "e:/temporary/ford-collins.osm"
+% ] ;
+% \stopMPpage
+
+\stoptext
+
+% -- -- The original approaches:
+% --
+% -- local colors = {
+% -- amenity = {
+% -- arts_centre = "osm:special",
+% -- ...
+% -- }
+% -- }
+% --
+% -- local function getcolor(r)
+% -- local what, color, both
+% -- for t in xmlcollected(r,"/tag") do
+% -- local at = t.at
+% -- local k = at.k
+% -- local all = usedcolors[k]
+% -- if all then
+% -- local v = at.v
+% -- local col = all[v]
+% -- if col then
+% -- what = k
+% -- color = col
+% -- both = lines[k]
+% -- elseif missing then
+% -- missing[k][v] = (missing[k][v] or 0) + 1
+% -- end
+% -- end
+% -- if k == "amenity" then
+% -- break
+% -- end
+% -- end
+% -- return what, color, both
+% -- end
+%
+% -- -- maybe nested:
+%
+% -- for m in xmlcollected(parent,"/member[@type='relation']") do
+% -- local f = xmlfirst(root,f_relation(m.at.ref))
+% -- if f then
+% -- for m in xmlcollected(f,"/member[@type='way']") do
+% -- -- local f = xmlfirst(root,f_way(m.at.ref))
+% -- local f = ways[m.at.ref]
+% -- if f then
+% -- local p, n = addpath(f, { }, 0)
+% -- if n > 1 then
+% -- local what, color = getcolor(parent)
+% -- if what and rendering[what] then
+% -- r = r + 1
+% -- if p[1] == p[n] then
+% -- result[r] = f_fill(p,color)
+% -- else
+% -- result[r] = f_draw(p,color)
+% -- end
+% -- end
+% -- end
+% -- end
+% -- end
+% -- end
+% -- end
+%
+% -- local filename = resolvers.savers.virtual("foo",result,"mp")
+% -- context([[input "%s" ;]],filename)
+% -- context([[runscript "resolvers.cleaners.virtual('%s')" ;]],filename)
+%
+% -- context.startTEXpage()
+% -- context.startMPcode("doublefun")
+% -- context("lua.mp.fetchresult();")
+% -- context.stopMPcode()
+% -- context.stopTEXpage()
+