Git Product home page Git Product logo

sequentially-generate-planet-mbtiles's Introduction

Sequentially Generate Planet Mbtiles

Sequentially generate and merge an entire planet.mbtiles vector tileset on low memory/power hardware for free.

TL;DR give me planet vector tiles! (usage)

  1. Have Docker installed.
  2. Download the latest binary for your operating system from the release page
  3. sudo ./sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0
  4. Rejoice! See acknowledgements below for people to thank.

Configuration

config.json

sudo ./sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0 -c /path/to/config.json
// config.json
// Note if a config.json is provided, the program will ignore all other flags set.
{
  "pbfFile": "",
  "workingDir": "",
  "outDir": "",
  "excludeOcean": false,
  "excludeLanduse": false,
  "TilemakerConfig": "",
  "TilemakerProcess": "",
  "maxRamMb": 0,
  "outAsDir": false,
  "skipSlicing": false,
  "mergeOnly": false,
  "skipDownload": false
}

pbfFile - By default, the program downloads the latest planet data directrly from OpenStreetMaps. However, if you already have your own pbf file that you would like to use (for example, you may have a historical data set, or subset of the planet), you can provide the path to it here.

workingDir - This is where files will be downloaded to and files generated as a result of processing osm data will be stored. Temporary files will be stored here. Please ensure your designated working directory has at least 300 GB of space available. If none is provided, a 'data' folder will be created in the current working directory.

outDir - This is where the final planet.mbtiles file (or folder tree if outAsDir is true) will be placed.

excludeOcean - By default the program will download the appropriate ocean/sea data and include it in the final output planet.mbtiles. If you do not wish to include the sea tiles (for example to save a little space), then you can set this option to true. If true, the ocean data will not be downloaded either. This can significantly increase the overall speed of generation as there are a lot of ocean tiles and writing them all often manifests as a filesystem io bottleneck. A planet map without ocean tiles however does look strange and empty (it can be hard to identify continent borders etc) - if your target end user is, for example, a customer who expects a pretty map, we would recommend they be included.

excludeLanduse - By default the program will download the appropriate landuse/landcover data and include it in the final output planet.mbtiles. If you do not wish to include the landcover overlay (for example to save a little space), then you can set this option to true. If true, the landuse data will not be downloaded either.

TilemakerConfig - [note capitalisation] The path to the config file that will be passed to Tilemaker. See the default used here. This will affect things like tags etc which will affect your front end styles when serving. It is reccomended to leave as default (blank) unless you have a specific reason to make changes (for example, you require a language other than english to be the primary language for the generated maps, or wish to change the zoom level (14 by default)).

TilemakerProcess - [note capitalisation] The path to the process file that will be passed to Tilemaker. See the default used here. Leaving blank will use the default. You can also use a special value to select one of the provided process files to match a given style. The special values are "tileserver-gl-basic", "sgpm-bright". Copies of the target styles can be viewed here. Feel free to copy one of the target styles to your front end project if necessary.

maxRamMb - Provide the maximum amount of RAM in MB that the process should use. If a linux os is detected, the total system RAM will be detected from /proc/meminfo and a default will be set to a reasonably safe level, maximising the available resources. This assumes that only a minimal amount of system RAM is currently being used (such as an idle desktop environment (<2G)). If you are having memory problems, consider manually setting this flag to a reduced value. Note this is not guaranteed and some margin should be allowed for. The default is set to 4096 if the amount of available ram cannot be detected. This setting is not a hard cap and the program will bleed over if necessary and possible.

outAsDir - The final output will be a directory of tiles rather than a single mbtiles file. This will generate hundreds of thousands of files in a predetermined directory structure. More information can ba found about this format and why you might use it over a single mbtiles file can be found here

skipSlicing - Skips the intermediate data processing/slicing and looks for existing files to convert into mbtiles in [workingDir]/pbf/slices. This is useful if you wish to experiment with different Tilemaker configs/process (for example if you wish to change the zoom levels or style tagging of the final output). Once the existing files have been converted to mbtiles, they will be merged either to a single file, or to a directory, respecting the -od flag.

mergeOnly - Skips the entire generation process and instead looks for existing mbtiles in [workingDir]/mbtiles and merges them into a single planet.mbtiles file in the [outDir]. This is useful if you already have a tilesets you wish to merge.

skipDownload - Skips planet downloading - must be set with skip slicing or merge only. Note, this should not be used if you have your own pbf file you wish to slice. In that case, just supply a path to the file in the pbfFile option and the download will be skipped anyway.

Flags

All options in the config.json can be set with flags. Options unique to flags are:

-h, --help - Print the help message listing all available flags.

-v, --version - Print version information.

-s, --stage - Initialise required containers, Dirs and logs based on the supplied config file and then exit. Can be useful to check you are running with correct permissions etc (for example Docker and filesystem), but without running the hard work. It will take some time to build the required containers.

-c, --config - Provide path to a config.json. No configuration is required. If a config.json is provided, all other "config flags" are ignored and runtime params are derived solely from the config.json. See documentation for example config.json

-t, --test - Will run the entire program on a much smaller dataset (morocco-latest.osm.pbf). The program will download the test data and generate a planet.mbtiles from it. This is useful for testing both the output and that your system meets the requirements. You cannot set any other flags in conjunction with this flag. if you wish to run your own custom test then please set a config.json file with your own smaller dataset and other options.

Why?

There are some wonderful options out there for generating and serving your own map data and there are many reasons to want to do so. My reason, and the inspiration for this program was cost. It is expensive to use a paid tile server option after less users using it than you might think. The problem is, when trying to host your own, a lot of research has shown me that almost all solutions for self generating tiles for a map server require hugely expensive hardware to even complete (it's not uncommon to see requirements for 64 cores and 128 GB RAM!); indeed the largest I've seen wanted 150 GB of the stuff! (for generating the planet that is). If you want a small section of the world, then it is much easier, but I need the planet - so what to do? Generate smaller sections of the world, then combine them.

That's where sequentially-generate-planet-mbtiles comes in. It downloads the latest osm data (or uses your supplied pbf file), splits it into manageable chunks, generates mbtiles from those chunks and then stitches it all together.

This program aims to be a simple set and forget, one liner which gives anyone - a way to get a full-featured and bang up to date set of vector tiles for the entire planet on small hardware.

It's also designed (work in progress) to be fail safe - meaning that if your hardware (or our software) does crash mid process, you have not lost all your data, and you are able to resume the work where the program left off.

This also uses the openmaptiles mbtiles spec (by default but this can be changed), meaning that when accessing the served tiles you can easily use most of the open source styles available. See our included styles which we can target - you may wish to use those on your front end for a quick setup. More information on styles can be found below.

Considerations

  1. Hardware usage - this will consume effectively 100% CPU for up to a few days and will also do millions of read/writes from ssd/RAM/CPUcache. While modern hardware and vps' are perfectly capable of handling this, if you are using old hardware, beware that its remaining lifespan may be significantly reduced.
  2. Cost - related to the above, while this program and everything it uses is entirely free and open source - the person's/company's computer you're running it on might charge you electricity/load costs etc. Please check with your provider, how they handle fair use.
  3. Time - your hardware will be unable to do anything much other than run this program while it is running. This is in order to be efficient and is by design. If your hardware is hosting other production software or will be needed for other things in the next few days, be aware that it will perform suboptimally while this is running.
  4. Bandwidth - this will download the entire planet's worth of openstreetmap data directly from OSM. At the time of writing, this is approx. 64 GB. **Please note: ** the program will look for a planet-latest.osm.pbf file in the data/pbf folder. If this is already present, it will skip the download and use this file. If you already have the data you wish to generate mbtiles for, you can place it there to skip the download. This can be useful if you want historical data, or are generating the mbtiles on multiple computers.
  5. Data generation - in order to remain relatively fast on low spec hardware, this program systematically breaks up the OSM data into more manegable chunks before processing. Therefore, expect around 300 GB of storage to be used up on completion.

Requirements

Hardware

  1. About 300 GB clear disk space for the entire planet. Probably an SSD unless you like pain, suffering and the watching the slow creep of old age.
  2. About 3 GB of clear RAM (so maybe 4/5 GB if used on a desktop pc). We are working on options in the future for lower RAM requirements.
  3. Time. As above, this has been written to massively streamline the process of getting a planetary vector tile set for the average person who might not have the strongest hardware or the desire to spend £££ on a 64 core 128 GB RAM server. Unfortunately, if you cut out the cost, you increase the time. Expect the process to take a couple of days from start to finish on small/old hardware.

Software

  1. Have Docker installed.

Serving mbtiles

Software

We would recommend something like tileserver-gl as a good place to start. Further reading can be found on the openstreetmap wiki.

You can quickly serve using tileserver-gl (remember to mount the correct volume containing your planet.mbtiles):

docker run --rm -it -v $(pwd)/data/out:/data -p 8080:80 maptiler/tileserver-gl

Styles

The default output of sequentially-generate-planet-mbtiles looks to match with the open source tileserver-gl 'Basic' style.

When accessing your tileserver with something like MapLibre from a front end application, a good place to start would be passing it a copy of the above style, making sure to edit the urls to point to the correct places.

You can edit the output of sequentially-generate-planet-mbtiles by providing a customised process or config file through the config file. We also have built in support for targeting the open source OSM 'Bright' style.

Some style considerations

If making your own style or editing an existing one, note that sequentially-generate-planet-mbtiles by default will write text to the name:latin tag. If your maps are displayed, but missing text, check that your style is looking for name:latin and not something else (e.g. simply name).

Pay attention to your fonts. The OSM Bright style makes use of Noto Sans variants (bold, italic & regular). If you are using tileserver-gl to serve your tiles, it only comes with the regular variant of Noto Sans (not the bold or the italic); therefore, it may look like text labels are missing since the style won't be able to find the fonts. You should therefore consider editing the style and changing all mentions of the font to use only the regular variant. Alternatively, you could ensure that all fonts necessary are present.

FAQ

  1. How long will this take? We are pleased to anounce that the new version 3 slicing algorithm is seen to be about twice as fast as the one used in version 2. An average 8core CPU/16 GB pc should take less than 24 hours (download speed often being the largest cause of variance).
  2. Do I have to download the entire planet? No! If you already have a pbf file of your own that you would like to generate and mbtiles file from, you can provide it as the pbfFile in the config (or with flags). Support is comming in the future for continent processing (meaning if you want 'Africa' for example, in the future you should be able to pass that as a flag and we will take care of the rest).
  3. Would I use this if I have powerful hardware? Maybe. Since the program essentially saves its progress as it goes, even if you have strong hardware, you are reducing the time taken to redo the process in the event of a crash or file corruption. Further, the RAM is what is really saved here so if you have say 32 cores and 64 GB RAM, you still would not be able to generate the entire planet by loading it into memory. Additionally, it just saves time configuring everything.
  4. Why do I have to run part of the program with 'sudo' privileges? Many docker installations require sudo to be executed. You may not have to execute the program with sudo.
  5. Does 'low spec' mean I can run it on my toaster? Maybe, but mostly not. But you can happily run it on you 4core CPU/4 GB RAM home pc without too much trouble. Just time.
  6. Why would I use this over Planetiler? Planetiler is a fantastic project, however it still requires over 32 GB RAM to complete the entire planet (0.5x the size of the planet pbf file).

Examples

Use all defaults (download all required data and generate a planet.mbtiles file):

sudo ./sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0

Providing a config.json:

sudo ./sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0 -c /path/to/config.json

Use a specific source file, and send the output to a specific place. Target style to match sgpm-bright:

sudo ./sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0 -p /path/to/planet-latest.osm.pbf -o /path/to/output/dir -tp sgpm-bright

Acknowledgements

Please take the time to thank the folks over at tilemaker, tippecanoe, osmium and gdal. They are the reason any of this is possible in the first place. It goes without saying, our thanks go out to OpenStreetMap.

Attribution

Please attribute openmaptiles, openstreemap contributors and tippecanoe if any data derived from this program is used in production.

Licenses

Files generated by sequentially-generate-planet-mbtiles are subject to the licenses described by tippecanoe and OpenStreetMap. All third party licences can be found in the relevant submodule to this repo. We encourage you to consider them carefully, as always.

sequentially-generate-planet-mbtiles is subject to the MIT license.

Contributions

All welcome! Feature request, pull request, bug reports/fixes etc - go for it.

Version 2 (old)

See the version 2 README.

Currently working on:

  • v4.0.0 milestone - add automatic fetching of pbf files for continents to use instead of the planet.
  • v4.0.0 milestone - ability to download and merge osm updates to existing mbtiles.

sequentially-generate-planet-mbtiles's People

Contributors

lambdajack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

sequentially-generate-planet-mbtiles's Issues

Ubuntu 22.04 Osmium problem

Hi,

I have clean install of Ubuntu 22.04 and latest package. When started I got this errors:

CMake Warning at cmake/FindOsmium.cmake:190 (message):
Osmium: GEOS library is required but not found, please install it or
configure the paths.
Call Stack (most recent call first):
CMakeLists.txt:173 (find_package)

-- Could NOT find GDAL (missing: GDAL_LIBRARY GDAL_INCLUDE_DIR) (found version "GDAL_VERSION-NOTFOUND")
CMake Warning at cmake/FindOsmium.cmake:204 (message):
Osmium: GDAL library is required but not found, please install it or
configure the paths.
Call Stack (most recent call first):
CMakeLists.txt:173 (find_package)

CMake Warning at cmake/FindOsmium.cmake:220 (message):
Osmium: PROJ.4 library is required but not found, please install it or
configure the paths.
Call Stack (most recent call first):
CMakeLists.txt:173 (find_package)

-- Could NOT find Osmium (missing: GEOS_INCLUDE_DIR GEOS_LIBRARY GDAL_FOUND PROJ_INCLUDE_DIR PROJ_LIBRARY)
-- Use C++ version: c++11
-- Looking for cppcheck
-- Looking for cppcheck - not found
-- Build target 'cppcheck' will not be available.
-- Configuring documentation
-- Looking for doxygen
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
-- Looking for doxygen - not found
-- Disabled making of documentation.
-- Configuring documentation - done
-- Looking for clang-tidy
-- Looking for clang-tidy - not found
-- Build target 'clang-tidy' will not be available.
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:

INSTALL_PROTOZERO

...

             from /var/install/osmium-tool/src/export/export_format_spaten.hpp:4,
             from /var/install/osmium-tool/src/export/export_format_spaten.cpp:2:

In static member function 'static const unsigned char* osmium::Tag::after_null(const unsigned char*)',
inlined from 'const unsigned char* osmium::Tag::next() const' at /var/install/libosmium/include/osmium/osm/tag.hpp:66:30,
inlined from 'osmium::memory::CollectionIterator& osmium::memory::CollectionIterator::operator++() [with TMember = const osmium::Tag]' at /var/install/libosmium/include/osmium/memory/collection.hpp:73:66,
inlined from 'bool ExportFormat::add_tags(const osmium::OSMObject&, TFunc&&) [with TFunc = ExportFormatSpaten::write_tags(const osmium::OSMObject&, protozero::pbf_builder<spaten_pbf::Feature>&)::<lambda(const osmium::Tag&)>]' at /var/install/osmium-tool/src/export/export_format.hpp:75:9:
/var/install/libosmium/include/osmium/osm/tag.hpp:58:113: warning: offset '5' outside bounds of constant string [-Warray-bounds]
58 | return reinterpret_cast<const unsigned char*>(std::strchr(reinterpret_cast<const char*>(ptr), 0) + 1);
| ^
/var/install/libosmium/include/osmium/osm/tag.hpp:58:113: warning: offset '5' outside bounds of constant string [-Warray-bounds]
/var/install/libosmium/include/osmium/osm/tag.hpp:58:113: warning: offset '5' outside bounds of constant string [-Warray-bounds]
/var/install/libosmium/include/osmium/osm/tag.hpp:58:113: warning: offset '5' outside bounds of constant string [-Warray-bounds]
[ 67%] Building CXX object test/CMakeFiles/unit_tests.dir//src/export/export_format_text.cpp.o
[ 68%] Building CXX object test/CMakeFiles/unit_tests.dir/
/src/export/export_handler.cpp.o
[ 69%] Building CXX object test/CMakeFiles/unit_tests.dir//src/extract/extract_bbox.cpp.o
[ 70%] Building CXX object test/CMakeFiles/unit_tests.dir/
/src/extract/extract.cpp.o
[ 70%] Building CXX object test/CMakeFiles/unit_tests.dir//src/extract/extract_polygon.cpp.o
[ 71%] Building CXX object test/CMakeFiles/unit_tests.dir/
/src/extract/geojson_file_parser.cpp.o
[ 72%] Building CXX object test/CMakeFiles/unit_tests.dir//src/extract/geometry_util.cpp.o
[ 73%] Building CXX object test/CMakeFiles/unit_tests.dir/
/src/extract/osm_file_parser.cpp.o
In file included from /var/install/libosmium/include/osmium/area/detail/basic_assembler.hpp:42,
from /var/install/libosmium/include/osmium/area/detail/basic_assembler_with_tags.hpp:37,
from /var/install/libosmium/include/osmium/area/assembler.hpp:37,
from /var/install/osmium-tool/src/extract/osm_file_parser.cpp:27:
In member function 'TDerived& osmium::builder::OSMObjectBuilder<TDerived, T>::set_user(const char*) [with TDerived = osmium::builder::AreaBuilder; T = osmium::Area]',
inlined from 'void osmium::builder::AreaBuilder::initialize_from_object(const osmium::OSMObject&)' at /var/install/libosmium/include/osmium/builder/osm_object_builder.hpp:591:25,
inlined from 'bool osmium::area::Assembler::create_area(osmium::memory::Buffer&, const osmium::Relation&, const std::vector<const osmium::Way*>&)' at /var/install/libosmium/include/osmium/area/assembler.hpp:85:47,
inlined from 'bool osmium::area::Assembler::operator()(const osmium::Relation&, const std::vector<const osmium::Way*>&, osmium::memory::Buffer&)' at /var/install/libosmium/include/osmium/area/assembler.hpp:216:40,
inlined from 'bool osmium::area::Assembler::operator()(const osmium::Relation&, const std::vector<const osmium::Way*>&, osmium::memory::Buffer&)' at /var/install/libosmium/include/osmium/area/assembler.hpp:179:18,
inlined from 'void osmium::area::MultipolygonCollector::complete_relation(const osmium::relations::RelationMeta&) [with TAssembler = osmium::area::Assembler]' at /var/install/libosmium/include/osmium/area/multipolygon_collector.hpp:190:30,
inlined from 'bool osmium::relations::Collector<TCollector, TNodes, TWays, TRelations>::find_and_add_object(const osmium::OSMObject&) [with TCollector = osmium::area::MultipolygonCollectorosmium::area::Assembler; bool TNodes = false; bool TWays = true; bool TRelations = false]' at /var/install/libosmium/include/osmium/relations/collector.hpp:412:74,
inlined from 'void osmium::relations::Collector<TCollector, TNodes, TWays, TRelations>::HandlerPass2::way(const osmium::Way&) [with TCollector = osmium::area::MultipolygonCollectorosmium::area::Assembler; bool TNodes = false; bool TWays = true; bool TRelations = false]' at /var/install/libosmium/include/osmium/relations/collector.hpp:149:61,
inlined from 'void osmium::detail::apply_item_impl(TItem&, THandler&&) [with THandler = osmium::relations::Collector<osmium::area::MultipolygonCollectorosmium::area::Assembler, false, true, false>::HandlerPass2&; TItem = osmium::memory::Item]' at /var/install/libosmium/include/osmium/visitor.hpp:65:32,
inlined from 'void osmium::apply_item(TItem&, THandlers&& ...) [with TItem = memory::Item; THandlers = {handler::NodeLocationsForWays<index::map::VectorBasedSparseMap<long unsigned int, Location, index::map::StdVectorWrap>, index::map::Dummy<long unsigned int, Location> >&, relations::Collector<area::MultipolygonCollectorarea::Assembler, false, true, false>::HandlerPass2&}]' at /var/install/libosmium/include/osmium/visitor.hpp:308:37,
inlined from 'void osmium::apply_impl(TIterator, TIterator, THandlers&& ...) [with TIterator = io::InputIteratorio::Reader; THandlers = {handler::NodeLocationsForWays<index::map::VectorBasedSparseMap<long unsigned int, Location, index::map::StdVectorWrap>, index::map::Dummy<long unsigned int, Location> >&, relations::Collector<area::MultipolygonCollectorarea::Assembler, false, true, false>::HandlerPass2&}]' at /var/install/libosmium/include/osmium/visitor.hpp:320:23,
inlined from 'void osmium::apply(TIterator, TIterator, THandlers&& ...) [with TIterator = io::InputIteratorio::Reader; THandlers = {handler::NodeLocationsForWays<index::map::VectorBasedSparseMap<long unsigned int, Location, index::map::StdVectorWrap>, index::map::Dummy<long unsigned int, Location> >&, relations::Collector<area::MultipolygonCollectorarea::Assembler, false, true, false>::HandlerPass2&}]' at /var/install/libosmium/include/osmium/visitor.hpp:327:19:
/var/install/libosmium/include/osmium/builder/osm_object_builder.hpp:473:45: warning: 'size_t strlen(const char*)' reading 1 or more bytes from a region of size 0 [-Wstringop-overread]
473 | const auto len = std::strlen(user);
| ~~~~~~~~~~~^~~~~~
In file included from /var/install/libosmium/include/osmium/memory/buffer.hpp:38,
from /var/install/osmium-tool/src/extract/osm_file_parser.hpp:26,
from /var/install/osmium-tool/src/extract/osm_file_parser.cpp:23:
/var/install/libosmium/include/osmium/osm/entity.hpp: In function 'void osmium::apply(TIterator, TIterator, THandlers&& ...) [with TIterator = io::InputIteratorio::Reader; THandlers = {handler::NodeLocationsForWays<index::map::VectorBasedSparseMap<long unsigned int, Location, index::map::StdVectorWrap>, index::map::Dummy<long unsigned int, Location> >&, relations::Collector<area::MultipolygonCollectorarea::Assembler, false, true, false>::HandlerPass2&}]':
/var/install/libosmium/include/osmium/osm/entity.hpp:64:11: note: at offset [34, 42] into source object 'osmium::OSMEntity::' of size 8
64 | class OSMEntity : public osmium::memory::Item {

It is still running so I just want to ask if this is ok or not:) Thank you!

Error building osmium in Debian Bullseye

Hi, I'm getting the following error:

Step 2/10 : RUN apt-get update
 ---> Running in c76f22718bd5
Get:1 http://deb.debian.org/debian bookworm InRelease [157 kB]
Get:2 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
Get:3 http://deb.debian.org/debian bookworm-updates InRelease [49.6 kB]
Get:4 http://deb.debian.org/debian bookworm/main amd64 Packages [8470 kB]
Fetched 8724 kB in 7s (1287 kB/s)
Reading package lists...
E: Problem executing scripts APT::Update::Post-Invoke 'rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true'
E: Sub-process returned an error code
The command '/bin/sh -c apt-get update' returned a non-zero code: 100
2022/08/30 15:16:45 containers.go:48: failed to build osmium container: exit status 100

When I run "apt-get update" outside of the container, it exits w/o error.

Some landcover files can not be found

First of all, thank you for this awesome project, this was exactly what I was looking for the whole time!

When the shapes are being read to write the .mbtiles the following error occurs. Is this to be expected or did the file locations change?

Bounding box -85, -85, -84, 85
Reading .shp ocean
Reading .shp urban_areas
Reading .shp ice_shelf
Reading .shp glacier
Sorting loaded shapes
Reading .pbf /pbf/95.osm.pbf
Unable to open landcover/ne_10m_urban_areas/ne_10m_urban_areas.shp or landcover/ne_10m_urban_areas/ne_10m_urban_areas.SHP.
Unable to open landcover/ne_10m_antarctic_ice_shelves_polys/ne_10m_antarctic_ice_shelves_polys.shp or landcover/ne_10m_antarctic_ice_shelves_polys/ne_10m_antarctic_ice_shelves_polys.SHP.
Unable to open landcover/ne_10m_glaciated_areas/ne_10m_glaciated_areas.shp or landcover/ne_10m_glaciated_areas/ne_10m_glaciated_areas.SHP.

Docker build fails on Windows:

Describe the bug
The v3.1.0 initial Docker build fails with/var/install/libosmium does not appear to contain CMakeLists.txt

Screenshots

> .\sequentially-generate-planet-mbtiles--win-amd64-v3.1.0.exe -c .\config.json
2023/04/11 12:28:04 using tileserver-gl-basic style target
2023/04/11 12:28:04 #
2023/04/11 12:28:04 loggers.go:26: #
2023/04/11 12:28:04 #
2023/04/11 12:28:04 sequentially-generate-planet-mbtiles started: &{srcFileProvided:false PbfFile:C:\Users\admin\Downloads\data\pbf\planet-latest.osm.pbf WorkingDir:C:\Users\admin\Downloads\data OutDir:C:\Users\admin\Downloads\tiles ExcludeOcean:false ExcludeLanduse:false TilemakerConfig:C:\Users\admin\AppData\Local\sequentially-generate-planet-mbtiles\tilemaker\resources\config-openmaptiles.json TilemakerProcess:C:\Users\admin\AppData\Local\sequentially-generate-planet-mbtiles\tilemaker\resources\process-openmaptiles.lua MaxRamMb:16000 OutAsDir:false SkipSlicing:false MergeOnly:false SkipDownload:false}
2023/04/11 12:28:04 git repo C:\Users\admin\AppData\Local\sequentially-generate-planet-mbtiles\gdal already exists, skipping clone
2023/04/11 12:28:04 git repo C:\Users\admin\AppData\Local\sequentially-generate-planet-mbtiles\osmium\osmium-tool already exists, skipping clone
2023/04/11 12:28:04 git repo C:\Users\admin\AppData\Local\sequentially-generate-planet-mbtiles\osmium\libosmium already exists, skipping clone
2023/04/11 12:28:04 git repo C:\Users\admin\AppData\Local\sequentially-generate-planet-mbtiles\tilemaker already exists, skipping clone
2023/04/11 12:28:04 git repo C:\Users\admin\AppData\Local\sequentially-generate-planet-mbtiles\tippecanoe already exists, skipping clone
failed to get console mode for stdin: The handle is invalid.
[+] Building 1.4s (11/14)
 => [internal] load build definition from Dockerfile                                                                                            0.0s
 => => transferring dockerfile: 758B                                                                                                            0.0s
 => [internal] load .dockerignore                                                                                                               0.0s
 => => transferring context: 2B                                                                                                                 0.0s
 => [internal] load metadata for docker.io/library/debian:bookworm-slim                                                                         0.9s
 => [ 1/10] FROM docker.io/library/debian:bookworm-slim@sha256:e54d36fb429ae2f8e102d5903e60aeb689bb26056ca2930f9d622ced90fbe730                 0.0s
 => [internal] load build context                                                                                                               0.0s
 => => transferring context: 42.48kB                                                                                                            0.0s
 => CACHED [ 2/10] RUN apt-get update                                                                                                           0.0s
 => CACHED [ 3/10] RUN apt-get update && apt-get install -y     libosmium2-dev libprotozero-dev libboost-program-options-dev libbz2-dev zlib1g  0.0s
 => CACHED [ 4/10] RUN mkdir /var/install                                                                                                       0.0s
 => CACHED [ 5/10] WORKDIR /var/install                                                                                                         0.0s
 => CACHED [ 6/10] COPY libosmium libosmium                                                                                                     0.0s
 => ERROR [ 7/10] RUN cd libosmium &&     mkdir build && cd build &&     cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=OFF -DBUILD_TESTING  0.3s
------
 > [ 7/10] RUN cd libosmium &&     mkdir build && cd build &&     cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DINSTALL_PROTOZERO=ON .. &&     make:
#11 0.315 CMake Warning:
#11 0.315   Ignoring extra path from command line:
#11 0.315
#11 0.315    ".."
#11 0.315
#11 0.315
#11 0.315 CMake Error: The source directory "/var/install/libosmium" does not appear to contain CMakeLists.txt.
#11 0.315 Specify --help for usage, or press the help button on the CMake GUI.
------
executor failed running [/bin/sh -c cd libosmium &&     mkdir build && cd build &&     cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DINSTALL_PROTOZERO=ON .. &&     make]: exit code: 1
2023/04/11 12:28:06 containers.go:48: failed to build osmium container: exit status 1

Desktop (please complete the following information):

  • Windows 10, updated
  • Docker Desktop 4.18.0

Missing tiles in generated mbtiles

Hello,

I've been using sequentially-generate-planet-mbtiles to create a file for whole planet. But I recently noticed that there are some missing tile, when serving my mbtile.

I also tried to create a mbtile only from Sao Paulo, in Brazil, but the problem also happens. Trying to generate mbtiles from other regions, the problem also happens.

Those missing tiles only appers from 14z level or above. Bellow 14z, the problem does not show, and you can see the problem in the following pics.

Captura de tela de 2023-10-25 13-44-28
Captura de tela de 2023-10-25 13-44-54

See an example of my config file:

{
  "pbfFile": "/home/felipe/Documentos/arquivos/PBFs/sudeste-latest.osm.pbf",
  "workingDir": "/home/felipe/Documentos/maptiler/maptile-generator/generated/sudeste",
  "outDir": "/home/felipe/Documentos/maptiler/maptile-generator/generated/sudeste",
  "excludeOcean": false,
  "excludeLanduse": false,
  "TilemakerConfig": "",
  "TilemakerProcess": "",
  "maxRamMb": 20000,
  "outAsDir": false,
  "skipSlicing": false,
  "mergeOnly": false,
  "skipDownload": true
}

Any idea of what may be causing this problem?

Exit status 137 from mbtiles.go:63 while generating planet

Describe the bug

Generating one of the temporary mbtiles dies with exist status 137

To Reproduce

Just run ./sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0, default settings, whole planet.

Expected behavior

Generation succeeds.

Screenshots

Output (excerpt):

2023/02/09 10:33:19 generating temporary mbtiles: /home/szabolcs.hodossy/data/mbtiles/9426803175.mbtiles from /home/szabolcs.hodossy/data/pbf/slices/1773301992-tmp.osm.pbf; directory output: false
mbtiles file exists, will overwrite (Ctrl-C to abort, rerun with --merge to keep)
Layer place (z0-14)
Layer boundary (z0-14)
Layer poi (z12-14)
Layer poi_detail (z14-14) -> poi
Layer housenumber (z14-14)
Layer waterway (z8-14)
Layer waterway_detail (z12-14) -> waterway
Layer transportation (z4-14)
Layer transportation_name (z8-14)
Layer transportation_name_mid (z12-14) -> transportation_name
Layer transportation_name_detail (z14-14) -> transportation_name
Layer building (z13-14)
Layer water (z6-14)
Layer ocean (z0-14) -> water
Layer water_name (z14-14)
Layer water_name_detail (z14-14) -> water_name
Layer aeroway (z11-14)
Layer aerodrome_label (z10-14)
Layer park (z11-14)
Layer landuse (z4-14)
Layer urban_areas (z4-8) -> landuse
Layer landcover (z0-14)
Layer ice_shelf (z0-9) -> landcover
Layer glacier (z2-9) -> landcover
Layer mountain_peak (z11-14)
Bounding box -180, -85.06, -134.982, 85.06
Reading .shp ocean
Shapefile entity #704 type 5 is invalid. Parts:232. Reason:Geometry has invalid self-intersections. A self-intersection point was found at (-146.579, -15.9312); method: i; operations: i/u; segment IDs {source, multi, ring, segment}: {0, 0, 138, 7}/{0, 0, 138, 9}... failed to correct. Reason: Geometry has invalid self-intersections. A self-intersection point was found at (-146.579, -15.9312); method: i; operations: i/u; segment IDs {source, multi, ring, segment}: {0, 0, 138, 7}/{0, 0, 138, 9}
Shapefile entity #51908 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51909 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51910 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51911 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51912 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51913 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51914 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51915 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51916 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51917 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51918 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51919 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51920 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51921 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51922 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51923 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51924 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51925 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51926 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51927 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51928 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51929 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51930 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51931 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51932 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51933 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51934 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51935 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51936 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51937 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51938 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51939 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51940 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51941 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51942 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51943 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51944 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51945 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51946 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51947 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51948 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51949 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51950 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51951 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51952 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #51953 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52268 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52269 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52270 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52271 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52272 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52273 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52274 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52275 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52276 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52277 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52278 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52279 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52280 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52281 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52282 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52283 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52284 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52285 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52286 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52287 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52288 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52289 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52290 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52291 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52292 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52293 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52294 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52295 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52296 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52297 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52298 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52299 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52300 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52301 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52302 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52303 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52304 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52305 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52306 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52307 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52308 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52309 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52310 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52311 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52312 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52313 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52628 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52629 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52630 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52631 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52632 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52633 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52634 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52635 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52636 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52637 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52638 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52639 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52640 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52641 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52642 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52643 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52644 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52645 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52646 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52647 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52648 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52649 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52650 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52651 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52652 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52653 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52654 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52655 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52656 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52657 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52658 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52659 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52660 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52661 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52662 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52663 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52664 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52665 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52666 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52667 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52668 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52669 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52670 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52671 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52672 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52673 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52988 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52989 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52990 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52991 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52992 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52993 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52994 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52995 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52996 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52997 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52998 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #52999 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53000 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53001 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53002 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53003 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53004 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53005 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53006 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53007 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53008 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53009 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53010 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53011 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53012 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53013 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53014 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53015 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53016 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53017 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53018 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53019 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53020 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53021 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53022 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53023 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53024 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53025 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53026 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53027 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53028 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53029 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53030 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53031 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53032 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Shapefile entity #53033 type 5 is invalid. Parts:1. Reason:Geometry has too few points... corrected
Reading .shp urban_areas
Reading .shp ice_shelf
Reading .shp glacier
Shapefile entity #360 type 5 is invalid. Parts:7. Reason:Geometry has invalid self-intersections. A self-intersection point was found at (-152.169, 78.8039); method: t; operations: u/u; segment IDs {source, multi, ring, segment}: {0, 0, 0, 5}/{0, 0, 0, 87}... corrected
Shapefile entity #1861 type 5 is invalid. Parts:1. Reason:Geometry has invalid self-intersections. A self-intersection point was found at (-155.982, -180); method: c; operations: x/i; segment IDs {source, multi, ring, segment}: {0, 0, -1, 224}/{0, 0, -1, 377}... corrected
Shapefile entity #1875 type 5 is invalid. Parts:54. Reason:Geometry has invalid self-intersections. A self-intersection point was found at (-141.942, 76.9594); method: t; operations: u/u; segment IDs {source, multi, ring, segment}: {0, 0, -1, 2543}/{0, 0, -1, 2505}... corrected
Sorting loaded shapes
Reading .pbf /src/1773301992-tmp.osm.pbf
Block 4007/4222 ways 0 relations 0
Sorting nodes
Block 4217/4222 ways 8000 relations 0
Sorting ways
Problem geometry relation 13121479: Boost.Geometry Centroid calculation exception
Problem geometry relation 9599691: Boost.Geometry Centroid calculation exception
Problem geometry relation 15006398: Boost.Geometry Centroid calculation exception
Problem geometry relation 4562026: Boost.Geometry Centroid calculation exception
Sorting generated geometriesions 8000
Stored 32065249 nodes, 102695 ways, 18264 relations
Shape points: 0, lines: 0, polygons: 7773
Generated points: 96335, lines: 1237744, polygons: 906896
2023/02/09 10:37:27 mbtiles.go:63: exit status 137

Desktop (please complete the following information):

Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-135-generic x86_64) with 8 GB RAM, 8 cores and 512 GB storage

where can I find the process-bright.lua

Hi,

I'm using this wonderful sgpm with the sgpm-bright style, and I have to customize the process.lua to import 'name' for my local language.
So I begin to learn how to customize the process.lua, but as I look into the sgpm code regarding the setting of TilemakerProcess to 'sgpm-bright'. I see that the code refer to process-bright.lua, but somehow, I couldn't find it?! Can you point me to where can I obtain the file?

if cfg.TilemakerProcess == "sgpm-bright" {
cfg.TilemakerProcess = filepath.Join(pth.temp, "tilemaker", "resources", "process-bright.lua")

Thank you,

  • Krisda - :D :D :D

Slicing fails with germany-latest.osm.pbf

Describe the bug
I tried to use this with germany-latest.osm.pbf from Geofabrik, but with fails to slice the file.
The extract should work, because I extracted a smaller region from with with osmium. tilemaker successfully creates tiles from that extract, but not from the whole thing, because I don't have enough RAM.
I don't know if this also happens with other extracts or the whole planet, I don't have enough storage to try it with the whole thing

To Reproduce
Steps to reproduce the behavior:

  1. Download germany-latest.osm.pbf from Geofabrik
  2. set the file pbfFile parameter in config.json to the downloaded file.
  3. run ./sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0 -c config.json

Expected behavior
The program slices the file and then generates tiles.

Screenshots

2022/09/13 16:49:07 attempting to use not more than 13746 MB of ram
2022/09/13 16:49:07 using tileserver-gl-basic style target
2022/09/13 16:49:07 #
2022/09/13 16:49:07 loggers.go:26: #
2022/09/13 16:49:07 #
2022/09/13 16:49:07 resumption of a previously stopped execution with different parameters detected
UNKNOWN THINGS CAN HAPPEN WHEN RESUMING WITH DIFFERENT PARAMETERS. You should only proceed if you are not confident that your changed parameters will have no adverse affect on the end result or are prepared to accept the outcome; otherwise you should clean the working/output directories and start again (you can save and replace downloaded files if requried). DO YOU WISH TO CONTINUE? yes/no
yes
2022/09/13 16:49:09 sequentially-generate-planet-mbtiles started: &{srcFileProvided:true PbfFile:/home/hz/Dokumente/osm/planet-sequencial/germany-latest.osm.pbf WorkingDir:/home/hz/Dokumente/osm/planet-sequencial/data OutDir:/home/hz/Dokumente/osm/planet-sequencial/build ExcludeOcean:false ExcludeLanduse:false TilemakerConfig:/home/hz/.cache/sequentially-generate-planet-mbtiles/tilemaker/resources/config-openmaptiles.json TilemakerProcess:/home/hz/.cache/sequentially-generate-planet-mbtiles/tilemaker/resources/process-openmaptiles.lua MaxRamMb:13746 OutAsDir:false SkipSlicing:false MergeOnly:false SkipDownload:false}
2022/09/13 16:49:09 git repo /home/hz/.cache/sequentially-generate-planet-mbtiles/gdal already exists, skipping clone
2022/09/13 16:49:09 git repo /home/hz/.cache/sequentially-generate-planet-mbtiles/osmium/osmium-tool already exists, skipping clone
2022/09/13 16:49:09 git repo /home/hz/.cache/sequentially-generate-planet-mbtiles/osmium/libosmium already exists, skipping clone
2022/09/13 16:49:09 git repo /home/hz/.cache/sequentially-generate-planet-mbtiles/tilemaker already exists, skipping clone
2022/09/13 16:49:09 git repo /home/hz/.cache/sequentially-generate-planet-mbtiles/tippecanoe already exists, skipping clone
2022/09/13 16:49:09 docker image sequential-osmium already built - proceeding without cached rebuild
2022/09/13 16:49:09 docker image sequential-gdal already built - proceeding without cached rebuild
2022/09/13 16:49:09 docker image sequential-tilemaker already built - proceeding without cached rebuild
2022/09/13 16:49:10 docker image sequential-tippecanoe already built - proceeding without cached rebuild
2022/09/13 16:49:10 source file provided - skipping planet download https://planet.openstreetmap.org/pbf/planet-latest.osm.pbf
2022/09/13 16:49:10 water-polygons-split-4326.zip already exists; skipping download.
2022/09/13 16:49:10 ne_10m_urban_areas.zip already exists; skipping download.
2022/09/13 16:49:10 ne_10m_antarctic_ice_shelves_polys.zip already exists; skipping download.
2022/09/13 16:49:10 ne_10m_glaciated_areas.zip already exists; skipping download.
2022/09/13 16:49:10 unzipping /home/hz/Dokumente/osm/planet-sequencial/data/water-polygons-split-4326.zip
2022/09/13 16:49:10 unzipping /home/hz/Dokumente/osm/planet-sequencial/data/ne_10m_urban_areas.zip
2022/09/13 16:49:10 unzipping /home/hz/Dokumente/osm/planet-sequencial/data/ne_10m_antarctic_ice_shelves_polys.zip
2022/09/13 16:49:10 unzipping /home/hz/Dokumente/osm/planet-sequencial/data/ne_10m_glaciated_areas.zip
2022/09/13 16:49:10 slice generation started; there may be significant gaps between logs
2022/09/13 16:49:10 target file size: 916 MB
2022/09/13 16:49:10 operating on: /home/hz/Dokumente/osm/planet-sequencial/germany-latest.osm.pbf
2022/09/13 16:49:10 tree.go:35: extract.go | Slicer | Failed to get extent: exit status 1

It does not change anything if I delete the working and output directories.

Desktop (please complete the following information):

  • OS: Fedora Workstation 36
  • Docker: podman-docker version 4.2.0

Coastline and Rivers broken on planet generation

I rendered a mbtiles set of the whole planet using sequentially-generate-planet-mbtiles on a virtual cloud server. The process completed after about a day and overall looks good, except for some coastline and river issues, for example in the north-eastern area of span and next for Tarifa (spain as well).

System

  • Host: Hetzner CPX51
  • OS: Ubuntu 20.04
  • 16 Cores, 32GB RAM
  • Version of Generator: unix-amd64-v3.1.0

Configuration

Run command:

$ ./sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0 -c config.json

config.json:

{
  "pbfFile": "./planet.osm.pbf",
  "workingDir": "./output/work",
  "outDir": "./output/out",
  "excludeOcean": false,
  "excludeLanduse": false,
  "TilemakerConfig": "",
  "TilemakerProcess": "",
  "maxRamMb": 0,
  "outAsDir": false,
  "skipSlicing": false,
  "mergeOnly": false,
  "skipDownload": true
}

Results:

Bildschirmfoto 2022-10-23 um 13 00 05

Bildschirmfoto 2022-10-23 um 13 00 15

Bildschirmfoto 2022-10-23 um 12 59 53

Bildschirmfoto 2022-10-23 um 12 59 36

Read info from database instead of pbf file.

Hello,

I have two questions about your project, and I'll be very pleased if you can answer them to me.

1 - I have an instance of a certain tool running in a vm, where this tool, read and extract all information from pbf files, to a postgres database.
I released that your tool, do almost the same thing, read all the information from a pbf file, and use this information to generated the mbtile file. My question is, is it possible to read the information from a database, instead of reading a pbf file?

2 - This tool may be used to build mbtile from a certain regions like, countries, e.g? I just tested this in a certain region in Brazil, I received a successful message, but, when I run a maptile-server pointing to the generated mbtile, the map have some bugs, not showing part of the map of the choosen region.

Produce same results as Planetiler (schema config)

It seems when using the project we don't get the same details as with Planetiler default schema (especially on displaying certain layers at certain zoom levels).

Any possibility to have an option to make ti in synch with Planetiler default schema ?

mbtiles.go:63: exit status 139

Error: mbtiles.go:63: exit status 139

env

No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.2 LTS
Release:	22.04
Codename:	jammy

Download pbf

Command:

sudo ./sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0 -p beijing.pbf

Output:

2023/07/18 13:51:48 attempting to use not more than 13824 MB of ram
2023/07/18 13:51:48 using tileserver-gl-basic style target
2023/07/18 13:51:48 #
2023/07/18 13:51:48 loggers.go:26: #
2023/07/18 13:51:48 #
2023/07/18 13:51:48 resumption of a previously stopped execution with different parameters detected
UNKNOWN THINGS CAN HAPPEN WHEN RESUMING WITH DIFFERENT PARAMETERS. You should only proceed if you are not confident that your changed parameters will have no adverse affect on the end result or are prepared to accept the outcome; otherwise you should clean the working/output directories and start again (you can save and replace downloaded files if requried). DO YOU WISH TO CONTINUE? yes/no
yes
2023/07/18 13:51:50 sequentially-generate-planet-mbtiles started: &{srcFileProvided:true PbfFile:/home/art/work/osm_data/beijing.pbf WorkingDir:/home/art/work/osm_data/data OutDir:/home/art/work/osm_data/data/out ExcludeOcean:false ExcludeLanduse:false TilemakerConfig:/home/art/.cache/sequentially-generate-planet-mbtiles/tilemaker/resources/config-openmaptiles.json TilemakerProcess:/home/art/.cache/sequentially-generate-planet-mbtiles/tilemaker/resources/process-openmaptiles.lua MaxRamMb:13824 OutAsDir:false SkipSlicing:false MergeOnly:false SkipDownload:false}
2023/07/18 13:51:50 git repo /home/art/.cache/sequentially-generate-planet-mbtiles/gdal already exists, skipping clone
2023/07/18 13:51:50 git repo /home/art/.cache/sequentially-generate-planet-mbtiles/osmium/osmium-tool already exists, skipping clone
2023/07/18 13:51:50 git repo /home/art/.cache/sequentially-generate-planet-mbtiles/osmium/libosmium already exists, skipping clone
2023/07/18 13:51:50 git repo /home/art/.cache/sequentially-generate-planet-mbtiles/tilemaker already exists, skipping clone
2023/07/18 13:51:50 git repo /home/art/.cache/sequentially-generate-planet-mbtiles/tippecanoe already exists, skipping clone
2023/07/18 13:51:50 docker image sequential-osmium already built - proceeding without cached rebuild
2023/07/18 13:51:50 docker image sequential-gdal already built - proceeding without cached rebuild
2023/07/18 13:51:50 docker image sequential-tilemaker already built - proceeding without cached rebuild
2023/07/18 13:51:50 docker image sequential-tippecanoe already built - proceeding without cached rebuild
2023/07/18 13:51:50 source file provided - skipping planet download https://planet.openstreetmap.org/pbf/planet-latest.osm.pbf
2023/07/18 13:51:50 water-polygons-split-4326.zip already exists; skipping download.
2023/07/18 13:51:50 ne_10m_urban_areas.zip already exists; skipping download.
2023/07/18 13:51:50 ne_10m_antarctic_ice_shelves_polys.zip already exists; skipping download.
2023/07/18 13:51:50 ne_10m_glaciated_areas.zip already exists; skipping download.
2023/07/18 13:51:50 unzipping /home/art/work/osm_data/data/water-polygons-split-4326.zip
2023/07/18 13:52:01 unzipping /home/art/work/osm_data/data/ne_10m_urban_areas.zip
2023/07/18 13:52:01 unzipping /home/art/work/osm_data/data/ne_10m_antarctic_ice_shelves_polys.zip
2023/07/18 13:52:01 unzipping /home/art/work/osm_data/data/ne_10m_glaciated_areas.zip
2023/07/18 13:52:02 previous progress detected; attempting to continue...
2023/07/18 13:52:06 previously incomplete: 117.535000, 39.420000, 117.525000, 41.080000
2023/07/18 13:52:08 slicing already complete; moving on to tile generation
2023/07/18 13:52:08 generating temporary mbtiles: /home/art/work/osm_data/data/mbtiles/9426803175.mbtiles from /home/art/work/osm_data/data/pbf/slices/3306528744-tmp.osm.pbf; directory output: false
Layer place (z0-14)
Layer boundary (z0-14)
Layer poi (z12-14)
Layer poi_detail (z14-14) -> poi
Layer housenumber (z14-14)
Layer waterway (z8-14)
Layer waterway_detail (z12-14) -> waterway
Layer transportation (z4-14)
Layer transportation_name (z8-14)
Layer transportation_name_mid (z12-14) -> transportation_name
Layer transportation_name_detail (z14-14) -> transportation_name
Layer building (z13-14)
Layer water (z6-14)
Layer ocean (z0-14) -> water
Layer water_name (z14-14)
Layer water_name_detail (z14-14) -> water_name
Layer aeroway (z11-14)
Layer aerodrome_label (z10-14)
Layer park (z11-14)
Layer landuse (z4-14)
Layer urban_areas (z4-8) -> landuse
Layer landcover (z0-14)
Layer ice_shelf (z0-9) -> landcover
Layer glacier (z2-9) -> landcover
Layer mountain_peak (z11-14)
Bounding box 116.45, 39.42, 117.525, 41.08
Reading .shp ocean
Reading .shp urban_areas
Reading .shp ice_shelf
Reading .shp glacier
Sorting loaded shapes
Reading .pbf /src/3306528744-tmp.osm.pbf
Block 122/138 ways 0 relations 0
Sorting nodes
terminate called after throwing an instance of 'std::out_of_range'
  what():  Could not find node with id 3589214908
2023/07/18 13:52:10 mbtiles.go:63: exit status 139

mbtiles can't be merged

In the final step of the process (when the mbtiles are being merged) the program tries to use a docker container that doesn't exist locally not on docker hub:

Unable to find image 'sequential-tippecanoe:latest' locally
docker: Error response from daemon: pull access denied for sequential-tippecanoe, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.

I didn't remove any build docker container locally though.

Documentation update

Update documentation about requirements.

Noticed that given requirements are bit low for today's planet content. Might be useful for others to reference this.

My hardware is:

  • AMD Ryzen 7 5800X 8-Core Processor
  • 32 GB RAM
  • OS: Fedora 37

Details of successful run:

  • RAM was just barely enough, I ended up with OOM killed Gnome desktop but luckily run 'sequentially-generate-planet-mbtiles--unix-amd64-v3.1.0' on tmux session where I was able to reconnect after DM restarts.
  • Disk space required was around 400 GB. I spared 1 TB SSD for the job and it was enough.
  • Time consumed was around 12 to 15 hours.

Result:

planet.mbtiles, size: 86 GB

Hope this helps and could be useful for documentation update.

Street names are cut off on higher zoom levels

I was able to successfully build a planet.mbtiles on my machine. When rendering the tiles with tileserver-gl I can see that on higher zoom levels the tiles borders are cutting of the highway numbers. Or at least neigbhoring tiles are not matching the cut off.

Is this to be expected due slicing that is being done for compartmentalizing the mbtile generation?

image

mbtiles.go:63: exit status 255

Good day,

I keep getting this on with latest version. It happens after server hours of various processing. Restarting the process gives sdame result.

root@openmaptiles:/disk1# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.4 LTS
Release: 20.04
Codename: focal

2022/11/14 22:33:20 SLICE: target 3097895965-tmp.osm.pbf requires further slicing
2022/11/14 22:33:20 operating on: /disk1/pbf/3097895965-tmp.osm.pbf
2022/11/14 22:33:21 slicing 3097895965-tmp.osm.pbf >>> 2855357057-tmp.osm.pbf (-0.010000,-90.000000,11.259375,90.000000)
2022/11/14 22:42:57 SLICE: 3097895965-tmp.osm.pbf >>> 2855357057-tmp.osm.pbf (-0.010000,-90.000000,11.259375,90.000000) success
2022/11/14 22:42:57 slicing 3097895965-tmp.osm.pbf >>> 1606289621-tmp.osm.pbf (11.239375,-90.000000,22.508750,90.000000)
2022/11/14 22:50:39 SLICE: 3097895965-tmp.osm.pbf >>> 1606289621-tmp.osm.pbf (11.239375,-90.000000,22.508750,90.000000) success
2022/11/14 22:50:39 SLICE: 2855357057-tmp.osm.pbf has reached target size; moving to safety.
2022/11/14 22:50:39 SLICE: 1606289621-tmp.osm.pbf has reached target size; moving to safety.
2022/11/14 22:50:39 SLICE: 1997111479-tmp.osm.pbf has reached target size; moving to safety.
2022/11/14 22:50:39 SLICE: 239617888-tmp.osm.pbf has reached target size; moving to safety.
2022/11/14 22:50:39 SLICE: 837367546-tmp.osm.pbf has reached target size; moving to safety.
2022/11/14 22:50:39 generating temporary mbtiles: /disk1/mbtiles/9426803175.mbtiles from /disk1/pbf/slices/1606289621-tmp.osm.pbf; directory output: false
Invalid JSON file.
2022/11/14 22:50:40 mbtiles.go:63: exit status 255

any help appreciated

Thank you

8080:80 or 8080:8080 ?

Hi lambdajack
in your README.md file there is the line:
docker run --rm -it -v $(pwd)/data/out:/data -p 8080:80 maptiler/tileserver-gl
should not it be 8080:8080 instead of 8080:80 ? At least, I could get it working with 8080:8080.
Best regards and thank you,
A.

temporary mbtiles, overlap after join (merge)

Temporary neighbour mbtiles are including the same polygons and are overlapping after merge

Expected behavior
The same data not to be included twice and overlap.

It seams that extract slices from osmium are overlapping
2023/07/25 09:22:40 SLICE: slovenia.osm.pbf >>> 3761385959-tmp.osm.pbf (13.305086,45.420805,14.962714,46.879555) success
2023/07/25 09:22:47 SLICE: slovenia.osm.pbf >>> 2949200230-tmp.osm.pbf (14.942714,45.420805,16.600342,46.879555) success

then "tile-join" should be smarter but as much as I understand it only copy's what it has.

Anybody knows solution to this?
sequential-part-vs-joined-overlap
sequential-joined-inspect
sequential-individual-mbtiles-before-join
sequential-vs-tilemaker-whole

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.