- Notifications
You must be signed in to change notification settings - Fork17
migurski/Dymo
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Dymo is a placement script for map labels, isolated from the purpose-built code inGeoIQ’s Acetate. Dymo resolves positions fordensely-packed point labels, and results in layouts make your maps look like they’ve beentouched by a cartographer.
Dymo usesSimulated Annealingto derive an acceptable global label set, described in Steven Wouderberg’sOctober 2007 presentationat Utrecht University. See an animation of the process over time in these twovideos of U.S. and European place names:
Demo area: Runmake geojson
to anneal labels for San Francisco and Israel sample areas from zooms 4 to 10. This will automatically build the data files, too (eg:make data
). Should run in less than an hour.
World: Annealing the entire world will take several days to several weeks and will require lots of RAM and many processor cores. Modify theMakefile
to remove the spatial filter as below:
# COMPOSITE FILTER (fast!)# SPATIAL_FILTER= --filter-bounding-box $(FILTER_SANFRANCISCO) --filter-bounding-box $(FILTER_JERUSALEM)# NO FILTER (slow! If no filter is desired, uncomment line below, comment out line above.)SPATIAL_FILTER=
You can change the fonts and population steps in the Makefile, too.
dymo-label.py
is a script that converts lists of cities with included fontinformation to GeoJSON point and label files suitable for use in geographicrendering.
Mamata Akella at the National Park Service has writtena detailed tutorial on Dymo and Tile Mill, to “avoid label overlaps and improve the overall legibility of park names dramatically.”The tutorial shows how to prepare data for Dymo using ArcGIS Desktop.
###Label Usage
Place U.S. city labels at zoom 6 for two minutes:
python dymo-label.py -z 6 --minutes 2 --labels-file labels.json --places-file points.json data/US-z6.csv.gz
Place U.S. city labels at zoom 5 over a 10000-iteration 10.0 - 0.01 temperature range:
python dymo-label.py -z 5 --steps 10000 --max-temp 10 --min-temp 0.01 -l labels.json -p points.json data/US-z5.csv
Both examples will result in a pair of GeoJSON files,labels.json
andpoints.json.
The first will contain rectangular label areas, the secondwill contain center points of places successfully positioned by Dymo. Becauselabels will collide in different ways depending on map scale, labels must beplaced separately for each zoom level:
For larger datasets, it’s almost always faster to rundymo-label.py
with the--minutes
option instead of--min-temp
/--max-temp
, because Dymo willautomatically partition labels based on mutual overlaps and perform many smallannealing processes.
Look indata/
for a list of zoom-by-zoom city locations, organized bycontinent and selected by Justin O’Bierne. Data is distributed separately fromcode, seedownloads for a link.
To prepare your own city lists or modify fonts and font sizes in input lists,Usedymo-prepare-places.py
to apply population-specific font choices toan in-bound list.
###Prepare-Places Usage
python dymo-prepare-places.py --font 0 fonts/Arial.ttf 10 --font 1000000 fonts/Arial.ttf 12 --zoom 5 data/North-America-all.txt.gz data/North-America-z5.txt
These sample images were created during the development of Acetate, and showthe results of town placement.
###Dymo Prepare Places
-z ZOOM, --zoom=ZOOM
- Maximum zoom level.Default value is4
.--zoom-field=ZOOM_FIELD
- Field to use for limiting selection by zoom.Default field iszoom start
.-f FONTS, --font=FONTS
- Additional font, in the form of three values: minimum population number (or other font field), font file path, font size. Can be specified multiple times.-r RADIUS, --radius=RADIUS
- Pixel buffer around each place.Default value is0
.--font-field=FONT_FIELD
- Field to use for font selection.Default field ispopulation
.--filter-field=FILTER_FIELD
- Field to use for limiting selection by theme and the value to limit by.Default is no filter.--symbol-size=SYMBOL_SIZE
- Size in pixels for implied townspot symbol width/height in pixels.Default size is8
.--symbol-size-field=SYMBOL_SIZE_FIELD
- Field to use for sizing the implied townspot symbol width/height in pixels.No default.
###Dymo Label
-m MINUTES, --minutes=MINUTES
- Number of minutes to run annealer. Longer run times generally give better results, to a point.Default value is2.0
.-z ZOOM, --zoom=ZOOM
- Map zoom level. Conflicts with--scale
and--projection
options.Default value is18
.-l LABELS_FILE, --labels-file=LABELS_FILE
-Optional: name of labels file to generate.-p PLACES_FILE, --places-file=PLACES_FILE
-Optional: name of place points file to generate.-r REGISTRATIONS_FILE, --registrations-file=REGISTRATIONS_FILE
-Optional: name of registration points file to generate. This file will have an additional "justified" field with values "left", "center", or "right".--min-temp=TEMP_MIN
- Optional: Minimum annealing temperature, for more precise control than specifying --minutes.--max-temp=TEMP_MAX
- Optional: Maximum annealing temperature, for more precise control than specifying --minutes.--steps=STEPS
- Number of annealing steps, for more precise control than specifying --minutes.--include-overlaps
- Include lower-priority places when they overlap higher-priority places.Default behavior is to skip the overlapping cities.--output-projected
- Optional: output projected coordinates.--projection=PROJECTION
- Optional: PROJ.4 string to use instead of default web spherical mercator.--blobs
- Load input as blobs rather than points, placing labels on top of locations instead of near them.--scale=SCALE
- Scale to use with --projection. Equivalent to +to_meter PROJ.4 parameter, which is not used internally due to not quite working in pyproj. Conflicts with --zoom option.Default value is1
.--dump-file=DUMP_FILE
- Optional: filename for a sequential dump of pickled annealer states. This all has to be stored in memory, so for a large job specifying this option could use up all available RAM.--dump-skip=DUMP_SKIP
- Optional: number of states to skip for each state in the dump file.--name-field=NAME_FIELD
- Name of column for labels to name themselves.Default value isname
.--placement-field=PLACEMENT_FIELD
- Optional: name of column for point placement. Default value ispreferred placement
.
###Advanced Prepare Places Usage
Use larger or smaller townspot symbol sizes:
--symbol-size
python dymo-prepare-places.py --symbol-size 6 --font 0 fonts/Arial.ttf 10 --font 1000000 fonts/Arial.ttf 12 --zoom 5 data/North-America-all.txt.gz data/North-America-z5.txt
Use custom townspot symbol size per feature:
--symbol-size-field
python dymo-prepare-places.py --symbol-size-field spotsize --font 0 fonts/Arial.ttf 10 --font 1000000 fonts/Arial.ttf 12 --zoom 5 data/North-America-all.txt.gz data/North-America-z5.txt
Use a custom 'population' attribute to size grade the text labels:
--font-field
python dymo-prepare-places.py --font-field rank --font 0 fonts/Arial.ttf 10 --font 1000000 fonts/Arial.ttf 12 --zoom 5 data/North-America-all.txt.gz data/North-America-z5.txt
Limit the initial visibility of a feature to a specific zoom:
--zoom-field
python dymo-prepare-places.py --zoom-field init_zoom --font 0 fonts/Arial.ttf 10 --font 1000000 fonts/Arial.ttf 12 --zoom 5 data/North-America-all.txt.gz data/North-America-z5.txt
Subselect features based on a simple filter:
--filter-field
python dymo-prepare-places.py --filter-field city_type capital_city --font 0 fonts/Arial.ttf 10 --font 1000000 fonts/Arial.ttf 12 --zoom 5 data/North-America-all.txt.gz data/North-America-z5.txt
Combo:
python dymo-prepare-places.py -z 6 --radius 1 --font 0 "fonts/Arial.ttf" 14 --font 4 "fonts/Arial Bold.ttf" 18 --font-field "sizeclass" master_data_file.tsv --zoom-field "zoom_start" --symbol-size-field "symbol_size" --filter-field region west west-labels-z6.txt
###Advanced Label Usage
Run longer, look prettier: adjust
--minutes
,--min-temp
,--max-temp
, and--steps
Use a custom
name
field: specify a custom--name-field
python dymo-label.py --name-field name_ascii -z 6 --minutes 2 --labels-file labels.json --places-file points.json data/North-America-z5.txt
Output multiple label, places, registration outputs: Use
--labels-file
,--places-file
, and--registrations-file
.python dymo-label.py --registrations-file registrations.json -z 6 --minutes 2 --labels-file labels.json --places-file points.json data/North-America-z5.txt
Provide label hints to the auto-label algorithm: Use
--placement-field
.python dymo-label.py --placement-field hint -z 6 --minutes 2 --labels-file labels.json --places-file points.json data/North-America-z5.txt
Manually troubleshoot overlaps in QGIS: Use
--include-overlaps
and open in QGIS and fine tune output.python dymo-label.py --include-overlaps -z 6 --minutes 2 --labels-file labels.json --places-file points.json data/North-America-z5.txt
Use a custom map projection: Use
--output-projected
,--projection
, and--scale
For an Albers map of the USA, but saved in WGS84 geographic coodinates:
python dymo-label.py --projection "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=38.0 +lon_0=-98.0 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs" --scale 2377 --steps 50000 --max-temp 230 --min-temp 0.0001 --labels-file northeast-labels.json east-labels-z3.txt --name-field "label" --placement-field "preferred_z3"
For an Albers map of the USA, saved in that projection:
python dymo-label.py --projection "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=38.0 +lon_0=-98.0 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs" --output-projected --scale 2377 --steps 50000 --max-temp 230 --min-temp 0.0001 --labels-file northeast-labels.json east-labels-z3.txt --name-field "label" --placement-field "preferred_z3"
Some of the advanced options, such as custom map projections, will require the following libraries:
- Modest Maps
- Shapely
- Pyproj
For projection-specific inputs, see thisprojections transform list.
Converting to Esri Shapefile format: UseGDAL/OGR's
ogr2ogr
tool to convert the GeoJSON Dymo output.QGIS, a free desktop GIS application, will also convert the files to SHP.ogr2ogr -f 'Esri Shapefile' -lco=UTF8 output.shp input.json
If you have OGR 1.9+ (for the UTF8 layer creation option to preserve the unicode place names), run
make shp
from the Dymo directory and the SHP versions will be automatically created.Reduce the file size of the GeoJSON output usingLil'JSON:
python LilJSON.py --precision 3 input.json output.json
Copyright 2010-2012 Michal Migurski, Nathaniel V. Kelso, and GeoIQ, offered under theBSD license. Uses Richard J. Wagner’sPython annealing library.
We’re not affiliated withDymo Corporation.