Giter Club home page Giter Club logo

planet-dump-ng's Introduction

Planet Dump (Next Generation)

Tool for converting an OpenStreetMap database dump into planet files.

By operating on the database dump rather than a running server, this means that running the extraction from PostgreSQL dump file to planetfile(s) is completely independent of the database server, and can be done on a disconnected machine without putting any load on any database.

The previous version of this tool required the database server to keep a consistent transaction context open for the duration of the dump, which would usually be several days. This created problems as the long-running transaction could get cancelled, meaning the planet dump would have to be started again from scratch.

Building

Before building the code, you will need:

  • A C++ build system (GCC 4.7 recommended),
  • libxml2 (version 2.6.31 recommended),
  • The Boost libraries (version 1.49 recommended),
  • libosmpbf (version 1.3.0 recommended),
  • libprotobuf and libprotobuf-lite (version 2.4.1 recommended)

To install these on Ubuntu, you can just type:

sudo apt-get install build-essential automake autoconf \
  libxml2-dev libboost-dev libboost-program-options-dev \
  libboost-date-time-dev libboost-filesystem-dev \
  libboost-thread-dev libboost-iostreams-dev \
  libosmpbf-dev osmpbf-bin libprotobuf-dev pkg-config

After that, it should just be a matter of running:

./autogen.sh
./configure
make

If you run into any issues with this, please file a bug on the github issues page for this project, giving as much detail as you can about the error and the environment it occurred in.

Running

The planet dump program has a decent built-in usage description, which you can read by running:

planet-dump-ng --help

One thing to note is that the program will create on-disk databases in the current working directory, so it is wise to run the program somewhere with plenty of fast disk space. Existing files may interfere with the operation of the program, so it's best to run it in its own, clean directory.

All files can be created in a default version (includes "uid" and "user" fields), and a "no-userinfo" version (without these fields).

Architecture

This started out with the aim of being easy to change in response to schema changes in the API. However, somehow the templates escaped and began to multiply. Sadly, the code is now much less readable than I would like, but on the bright side is a contender for the Most Egregiously Templated Code award.

Simplifying, the code consists of two basic parts; the bit which reads the PostgreSQL dump, and the part which writes XML and/or PBF.

The part which reads the PostgreSQL dump operates by launching "pg_restore" as a sub-process and parsing its output (in quite a naive way) to get the row data. The part which writes the XML and/or PBF then does a join between the top level elements like nodes, ways and relations and their "inners" - things like tags, way nodes and relation members.

In order that the system can output a planet file or a history planet file in the same run, both are generated from the history tables. The history planet file contains all these versions, but the planet file without history data ("current") does not. This requires a minor adjustment to how the non-history planet is written, with a filter which only keeps the most recent version of each element and does not output any elements which are flagged as deleted.

History

This evolved, by a somewhat roundabout route, from an attempt to create a new planet dump which read the absolute minimum from the database; that is changesets, changeset tags and just the IDs and versions of the current tables for nodes, ways and relations. The remaining information could be filled in at any time from the history tables because, with the minor exception of redactions, the nodes, ways and relations tables are append-only.

Dumping the IDs and versions would still take time, so it seemed worth looking at "pg_dump" to see how it would best be done efficiently. While looking at "pg_dump", it became clear that what was really needed was just the dump itself - a dump which is produced regularly for backup purposes anyway.

Tag sorting

Starting with version 1.2.0, planet-dump-ng sorts tags by the UTF-8 encoded bytes of the keys. Most keys use only ASCII characters, so this corresponds to an alphabetic ordering for those keys. Other keys will depend on how the codepoint is expressed in UTF-8. Values do not contribute to ordering.

planet-dump-ng's People

Contributors

pnorman avatar tomhughes avatar woodpeck avatar zerebubuth 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

Watchers

 avatar  avatar  avatar  avatar  avatar

planet-dump-ng's Issues

v1.2.4 fails to compile on Debian 11

Hi,

Installed all required dependencies on Debian 11 with apt and that worked fine. Both ./autogen.sh and ./configure also finished without errors. But make failed with this error:

Making all in src
make[1]: Entering directory '/usr/local/src/planet-dump-ng-1.2.4/src'
  CXX      changeset_filter.o
  CXX      changeset_map.o
  CXX      copy_elements.o
  CXX      dump_archive.o
  CXX      dump_reader.o
  CXX      extract_kv.o
  CXX      history_filter.o
  CXX      insert_kv.o
  CXX      output_writer.o
  CXX      pbf_writer.o
  CXX      planet-dump.o
  CXX      time_epoch.o
  CXX      types.o
  CXX      xml_writer.o
  CXXLD    ../planet-dump-ng
/usr/bin/ld: copy_elements.o: undefined reference to symbol 'pthread_condattr_setclock@@GLIBC_2.3.3'
/usr/bin/ld: /lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:408: ../planet-dump-ng] Error 1
make[1]: Leaving directory '/usr/local/src/planet-dump-ng-1.2.4/src'
make: *** [Makefile:611: all-recursive] Error 1

The versions of the packages installed:

autoconf 2.69-14
automake 1:1.16.3-2
libboost-date-time-dev 1.74.0.3
libboost-dev 1.74.0.3
libboost-filesystem-dev 1.74.0.3
libboost-iostreams-dev 1.74.0.3
libboost-program-options-dev 1.74.0.3
libboost-thread-dev 1.74.0.3
build-essential 12.9
libxml2-dev 2.9.10+dfsg-6.7+deb11u2
libosmpbf-dev 1.5.0-1+b1
osmpbf-bin 1.5.0-1+b1
pkg-config 0.29.2-1
libprotobuf-dev 3.12.4-1

Update github description

Experimental next version of the planet dump tool for OpenStreetMap.

This code is no longer experimental

Set osmosis_replication_base_url

OSM PBFs have the properties osmosis_replication_base_url and osmosis_replication_sequence_number. Even if we can't set the latter until #6 is figured out, the former should be set to https://planet.openstreetmap.org/replication/minute

PBF History file contains too large blobs

The history-2013-11-18.osm.pbf file contains at least one blob that is too large (> 32MiB).

The PBF Format says:
"The uncompressed length of a Blob should be less than 16 MiB (16_1024_1024 bytes) and must be less than 32 MiB."

PBF doesn't use DenseNodes

There are two ways to store Nodes in PBF files. In a similar format as Ways and Relations, which is used in planet-dump-ng, and as DenseNodes. DenseNodes result in significantly smaller PBF files. I tried reencoding the 30 GB planet-2013-11-18.osm.pbf file, which resulted in a 24 GB PBF file.

Planet state file

It's a pain to figure out which replication state.txt file corresponds to a given planet and, now that all the current & history for both XML and PBF correspond to the same state, it would make it easier if the dump process or script would figure out the state from which replication could continue.

The dump already tracks the last timestamp in the file, and this can be used to find a state file. But there might be in-progress transactions at that point, so it will be necessary to track backwards in the state files until before all those transactions start.

All member types of relation objects are from type="relation"

When I process the full history file (history-2014-xx-xx.osm.bz2) from here [1], all member types of relation objects are from type="relation". I think the issue can be found in the xml_writer.cpp [2]. I am not a cpp-expert, but the line 469-472 should be:

const char *type =
(rm_itr->member_type == nwr_node) ? "node" :
(rm_itr->member_type == nwr_way) ? "way" :
"relation";

Checking "member_type" instead of "member_id", right?

[1] http://planet.openstreetmap.org/planet/experimental/
[2] https://github.com/zerebubuth/planet-dump-ng/blob/master/src/xml_writer.cpp

Check references in current output

As seen in #13, problems with referential integrity in the "historic" tables can lead to producing broken "current-only" planet files. These problems should be detected and either corrected or abort the planet generation.

No separate changesets file.

Previous planet dumps also created a "changesets.osm" separately, for people who only wanted/needed the changesets. planet-dump-ng does not and, even though changesets are part of the XML dump, no-one wants to download 10s of GB to get at the 100s of MB of changesets.

Exception dumping recent planets

Planet has failed two weeks in a row now and this week I caught the output and it is throwing an exception dumping the relations to the PBF output:

Writing relations...
EXCEPTION: writer_thread(2): pbf_writer.cpp(189): Throw in function void pbf_writer::pimpl::write_blob(const google::protobuf::MessageLite&, const string&)
Dynamic exception type: boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::runtime_error> >
std::exception::what: Unable to write block of type OSMData, uncompressed size 33630260 because it is larger than the maximum allowed 33554432.

. Trying to continue...
EXCEPTION: pbf_writer.cpp(189): Throw in function void pbf_writer::pimpl::write_blob(const google::protobuf::MessageLite&, const string&)
Dynamic exception type: boost::wrapexcept<std::runtime_error>
std::exception::what: Unable to write block of type OSMData, uncompressed size 33723897 because it is larger than the maximum allowed 33554432.

Not sure if this is an issue in protozero (maybe @joto can help? we could rebuild against a newer version?) or whether planet-dump-ng is feeding it things that are too large.

Occasional lockups dumping planet

We've had a couple of instances - one in July (openstreetmap/operations#552) and one this week (openstreetmap/operations#568) where planetdump-ng has experienced some sort of thread deadlock and stopped making progress.

I grabbed a full backtrace of all threads this time (https://gist.github.com/tomhughes/250e1504f4689fc31a0ca4e0ab4e029e) and from analysing the output it looks like it had completed nodes and ways and was in the middle of the relations when it stopped.

Reference failures in planet file

The planet dump misses several nodes referenced in ways. This has happened before but I just verified it again in the current planet dump. I don't know whether this is an issue with the dump or a corrupted database.

Here is the list (generated with osmium check-refs -i -r):

n716017125 in w57766265
n716245610 in w57766265
n716031473 in w57766265
n716333274 in w57766265
n716159283 in w57766265
n716020535 in w57766265
n716289275 in w57766265
n716065281 in w57766265
n716344950 in w57766265
n716192814 in w57766265
n716022596 in w57766265
n716022746 in w57766265
n716318146 in w57766265
n716104954 in w57766265
n716348532 in w57766265
n716230965 in w57766265
n716025790 in w57766265
n716324576 in w57766265
n716142654 in w57766265
n716018533 in w57766265
n716263818 in w57766265
n716048451 in w57766265
n716342368 in w57766265
n716177856 in w57766265
n716021655 in w57766265
n716316492 in w57766265
n716084879 in w57766265
n716088615 in w57766265
n716347362 in w57766265
n716214529 in w57766265
n716024294 in w57766265
n716319541 in w57766265
n716123835 in w57766265
n716017377 in w57766265
n716248564 in w57766265
n716033847 in w57766265
n716334995 in w57766265
n716162910 in w57766265
n716020812 in w57766265
n716292204 in w57766265
n716068961 in w57766265
n716345393 in w57766265
n716195879 in w57766265
n716199671 in w57766265
n716023348 in w57766265
n716318339 in w57766265
n716108548 in w57766265
n716349425 in w57766265
n716234086 in w57766265
n716026036 in w57766265
n716326698 in w57766265
n716147905 in w57766265
n716018955 in w57766265
n716266652 in w57766265
n716052199 in w57766265
n716343943 in w57766265
n716181321 in w57766265
n716021831 in w57766265
n716316657 in w57766265
n716157113 in w57766265
n716019739 in w57766265
n716287014 in w57766265
n716062653 in w57766265
n716344834 in w57766265
n716190384 in w57766265
n716022476 in w57766265
n716317838 in w57766265
n716098736 in w57766265
n716348116 in w57766265
n716224030 in w57766265
n716024770 in w57766265
n716320046 in w57766265
n716136954 in w57766265
n716018123 in w57766265
n716258114 in w57766265
n716261525 in w57766265
n716045869 in w57766265
n716341165 in w57766265
n716175512 in w57766265
n716021521 in w57766265
n716300164 in w57766265
n716081995 in w57766265
n716346881 in w57766265
n716208756 in w57766265
n716023926 in w57766265
n716318918 in w57766265
n716117951 in w57766265
n716016991 in w57766265
n716242986 in w57766265
n716029868 in w57766265
n716332080 in w57766265
n716333746 in w57766265
n716160355 in w57766265
n716020580 in w57766265
n716290163 in w57766265
n716066269 in w57766265
n716345095 in w57766265
n716193440 in w57766265
n716022643 in w57766265
n716318030 in w57766265
n716102425 in w57766265
n716348260 in w57766265
n716227594 in w57766265
n716025470 in w57766265
n716322760 in w57766265
n716140087 in w57766265
n716018415 in w57766265
n716018573 in w57766265
n716264481 in w57766265
n716049630 in w57766265
n716342828 in w57766265
n716178763 in w57766265
n716021713 in w57766265
n716316536 in w57766265
n716085696 in w57766265
n716347099 in w57766265
n716212245 in w57766265
n716024098 in w57766265
n716319342 in w57766265
n716121240 in w57766265
n716017174 in w57766265
n716246424 in w57766265
n716032150 in w57766265
n716269442 in w57766265
n716055439 in w57766265
n716344518 in w57766265
n716184186 in w57766265
n716022145 in w57766265
n716316793 in w57766265
n716091458 in w57766265
n716347494 in w57766265
n716217718 in w57766265
n716024431 in w57766265
n716319719 in w57766265
n716126646 in w57766265
n716017528 in w57766265
n716251799 in w57766265
n716035943 in w57766265
n716336565 in w57766265
n716338074 in w57766265
n716168476 in w57766265
n716021184 in w57766265
n716295983 in w57766265
n716075157 in w57766265
n716345933 in w57766265
n716202197 in w57766265
n716023604 in w57766265
n716318543 in w57766265
n716111568 in w57766265
n716016458 in w57766265
n716236888 in w57766265
n716026179 in w57766265
n716328345 in w57766265
n716150598 in w57766265
n716019097 in w57766265
n716019591 in w57766265
n716275821 in w57766265
n716059083 in w57766265
n716344688 in w57766265
n716187185 in w57766265
n716022310 in w57766265
n716316981 in w57766265
n716095022 in w57766265
n716347780 in w57766265
n716220744 in w57766265
n716024592 in w57766265
n716319877 in w57766265
n716133323 in w57766265
n716017930 in w57766265
n716255180 in w57766265
n716038864 in w57766265
n716042127 in w57766265
n716339708 in w57766265
n716172110 in w57766265
n716021369 in w57766265
n716297927 in w57766265
n716078800 in w57766265
n716346729 in w57766265
n716205584 in w57766265
n716023767 in w57766265
n716318741 in w57766265
n716114580 in w57766265
n716016822 in w57766265
n716239985 in w57766265
n716026887 in w57766265
n716330408 in w57766265
n716153691 in w57766265
n716342127 in w57766265
n716177414 in w57766265
n716021632 in w57766265
n716316467 in w57766265
n716084274 in w57766265
n716346980 in w57766265
n716210889 in w57766265
n716024028 in w57766265
n716319175 in w57766265
n716119833 in w57766265
n716017101 in w57766265
n716244936 in w57766265
n716031279 in w57766265
n716333011 in w57766265
n716158940 in w57766265
n716020509 in w57766265
n716020751 in w57766265
n716291713 in w57766265
n716068435 in w57766265
n716345373 in w57766265
n716195512 in w57766265
n716022721 in w57766265
n716318125 in w57766265
n716104320 in w57766265
n716348368 in w57766265
n716230376 in w57766265
n716025766 in w57766265
n716324227 in w57766265
n716142038 in w57766265
n716018512 in w57766265
n716263257 in w57766265
n716047806 in w57766265
n716051676 in w57766265
n716343579 in w57766265
n716180702 in w57766265
n716021805 in w57766265
n716316634 in w57766265
n716087985 in w57766265
n716347339 in w57766265
n716213985 in w57766265
n716024240 in w57766265
n716319521 in w57766265
n716123259 in w57766265
n716017354 in w57766265
n716248394 in w57766265
n716033595 in w57766265
n716334746 in w57766265
n716162347 in w57766265
n716165385 in w57766265
n716020980 in w57766265
n716294321 in w57766265
n716071628 in w57766265
n716345716 in w57766265
n716198999 in w57766265
n716023236 in w57766265
n716318316 in w57766265
n716107961 in w57766265
n716349342 in w57766265
n716233492 in w57766265
n716026010 in w57766265
n716326388 in w57766265
n716147002 in w57766265
n716018871 in w57766265
n716266372 in w57766265
n716021296 in w57766265
n716297111 in w57766265
n716077071 in w57766265
n716346658 in w57766265
n716204193 in w57766265
n716023690 in w57766265
n716318647 in w57766265
n716113303 in w57766265
n716016606 in w57766265
n716238589 in w57766265
n716026285 in w57766265
n716329545 in w57766265
n716152391 in w57766265
n716019519 in w57766265
n716271210 in w57766265
n716057428 in w57766265
n716061148 in w57766265
n716344774 in w57766265
n716188838 in w57766265
n716022398 in w57766265
n716317519 in w57766265
n716097105 in w57766265
n716347856 in w57766265
n716222671 in w57766265
n716024677 in w57766265
n716319966 in w57766265
n716135713 in w57766265
n716018028 in w57766265
n716257014 in w57766265
n716040685 in w57766265
n716338894 in w57766265
n716170724 in w57766265
n716174040 in w57766265
n716021457 in w57766265
n716299353 in w57766265
n716080619 in w57766265
n716346814 in w57766265
n716207275 in w57766265
n716023856 in w57766265
n716318829 in w57766265
n716116359 in w57766265
n716016922 in w57766265
n716241976 in w57766265
n716028702 in w57766265
n716331356 in w57766265
n716155466 in w57766265
n716019672 in w57766265
n716282839 in w57766265
n716289022 in w57766265
n716064772 in w57766265
n716344926 in w57766265
n716192135 in w57766265
n716022573 in w57766265
n716317959 in w57766265
n716101045 in w57766265
n716348197 in w57766265
n716225738 in w57766265
n716025355 in w57766265
n716321460 in w57766265
n716138733 in w57766265
n716018255 in w57766265
n716260065 in w57766265
n716044136 in w57766265
n716340522 in w57766265
n716029456 in w57766265
n716331773 in w57766265
n716156556 in w57766265
n716019710 in w57766265
n716286680 in w57766265
n716061908 in w57766265
n716344814 in w57766265
n716189615 in w57766265
n716022448 in w57766265
n716317733 in w57766265
n716097924 in w57766265
n716347932 in w57766265
n716223256 in w57766265
n716024731 in w57766265
n716320017 in w57766265
n716136245 in w57766265
n716139653 in w57766265
n716018386 in w57766265
n716260840 in w57766265
n716045130 in w57766265
n716340861 in w57766265
n716175047 in w57766265
n716021495 in w57766265
n716300039 in w57766265
n716081305 in w57766265
n716346853 in w57766265
n716208332 in w57766265
n716023897 in w57766265
n716318889 in w57766265
n716117294 in w57766265
n716016964 in w57766265
n716242301 in w57766265
n716246021 in w57766265
n716031742 in w57766265
n716333445 in w57766265
n716159659 in w57766265
n716020551 in w57766265
n716289545 in w57766265
n716065561 in w57766265
n716344971 in w57766265
n716193094 in w57766265
n716022614 in w57766265
n716318001 in w57766265
n716101729 in w57766265
n716348237 in w57766265
n716226722 in w57766265
n716025437 in w57766265
n716322301 in w57766265
n716324805 in w57766265
n716143262 in w57766265
n716018546 in w57766265
n716264202 in w57766265
n716048862 in w57766265
n716342553 in w57766265
n716178050 in w57766265
n716021670 in w57766265
n716316505 in w57766265
n716085112 in w57766265
n716347028 in w57766265
n716211540 in w57766265
n716024069 in w57766265
n716319316 in w57766265
n716120438 in w57766265
n716017136 in w57766265
n716150011 in w57766265
n716019054 in w57766265
n716268928 in w57766265
n716054697 in w57766265
n716344490 in w57766265
n716183632 in w57766265
n716022115 in w57766265
n716316765 in w57766265
n716091012 in w57766265
n716347463 in w57766265
n716216620 in w57766265
n716024403 in w57766265
n716319690 in w57766265
n716126222 in w57766265
n716017500 in w57766265
n716250827 in w57766265
n716254467 in w57766265
n716038427 in w57766265
n716337810 in w57766265
n716167839 in w57766265
n716021153 in w57766265
n716295713 in w57766265
n716074654 in w57766265
n716345886 in w57766265
n716201834 in w57766265
n716023573 in w57766265
n716318514 in w57766265
n716110904 in w57766265
n716016421 in w57766265
n716236075 in w57766265
n716675623 in w57766265
n3593880569 in w353585683
n3593880569 in w353585683

Build instructions fail on `make`

Following the instructions on the README was straightforward enough but ended up failing in a way that's hard for me to make heads or tails of as a newcomer to this project. To replicate these difficulties, use the Dockerfile below with these arguments:
docker build . --build-arg pdng=1.1.3
docker build . --build-arg pdng=1.1.4

FROM ubuntu:18.04

ARG pdng=1.1.4

# update and add package to avoid apt warning
RUN apt-get update && apt-get install -y --no-install-recommends apt-utils

# utility libs
RUN apt-get install -y curl

# build requirements
RUN apt-get install -y build-essential automake autoconf \
  libxml2-dev libboost-dev libboost-program-options-dev \
  libboost-date-time-dev libboost-filesystem-dev \
  libboost-thread-dev libboost-iostreams-dev \
  libosmpbf-dev osmpbf-bin libprotobuf-dev pkg-config

# get/compile PlanetDumpNG
WORKDIR /root/
RUN curl -L https://github.com/zerebubuth/planet-dump-ng/archive/v${pdng}.tar.gz --output v${pdng}.tar.gz
RUN tar xvf v${pdng}.tar.gz

WORKDIR /root/planet-dump-ng-${pdng}/
RUN ./autogen.sh
RUN ./configure
RUN make  # failure :(

.

.

handle directory-based input for parallel pgdump

The OSM database is pretty hefty which means that dumping in as parallel a fashion as possible is desirable. Doing this, however, results in a directory output (https://www.postgresql.org/docs/9.4/static/backup-dump.html) and it looks right now as though planet-dump-ng expects a single file based on the documentation in planet-dump-ng --help and a little bit of digging in the source.

How difficult would it be to deal with the multipart table images created in parallel dumps?

Invalid xml data in planet osm

Don't know if I am right here. But I found the following data in the planet-210524.osm file. Opening tag (way) doesn't match to the closing tag (relation). Also "chaer type" seems not valid.

 <way id="933805767" timestamp="2021-04-22T09:46:48Z" version="1" chaer type="way" ref="182400916" role="inner"/>
  <member type="way" ref="182400928" role="inner"/>
  <member type="way" ref="182400935" role="inner"/>
  <member type="way" ref="182400910" role="inner"/>
  <member type="way" ref="182400991" role="inner"/>
  <member type="way" ref="182401067" role="inner"/>
  <member type="way" ref="182400927" role="inner"/>
  <member type="way" ref="182400934" role="inner"/>
  <member type="way" ref="182400921" role="inner"/>
  <member type="way" ref="182400925" role="inner"/>
  <member type="way" ref="182400985" role="inner"/>
  <member type="way" ref="182400907" role="inner"/>
  <member type="way" ref="182401094" role="inner"/>
  <member type="way" ref="182400940" role="inner"/>
  <member type="way" ref="182401005" role="inner"/>
  <member type="way" ref="182401080" role="inner"/>
  <member type="way" ref="182401092" role="inner"/>
  <member type="way" ref="182400972" role="inner"/>
  <member type="way" ref="182400983" role="inner"/>
  <member type="way" ref="182401068" role="inner"/>
  <member type="way" ref="182400942" role="inner"/>
  <member type="way" ref="182401019" role="inner"/>
  <member type="way" ref="182400989" role="inner"/>
  <member type="way" ref="182401004" role="inner"/>
  <member type="way" ref="182401022" role="inner"/>
  <member type="way" ref="182401075" role="inner"/>
  <member type="way" ref="182401077" role="inner"/>
  <member type="way" ref="182401069" role="inner"/>
  <member type="way" ref="182401041" role="inner"/>
  <member type="way" ref="182400978" role="inner"/>
  <member type="way" ref="182401090" role="inner"/>
  <member type="way" ref="182401029" role="inner"/>
  <member type="way" ref="182401031" role="inner"/>
  <member type="way" ref="182401017" role="inner"/>
  <member type="way" ref="182400995" role="inner"/>
  <member type="way" ref="182401061" role="inner"/>
  <member type="way" ref="182400986" role="inner"/>
  <member type="way" ref="182401056" role="inner"/>
  <member type="way" ref="182400959" role="inner"/>
  <member type="way" ref="182401057" role="inner"/>
  <member type="way" ref="182401058" role="inner"/>
  <member type="way" ref="182401078" role="inner"/>
  <member type="way" ref="182401086" role="inner"/>
  <tag k="natural" v="grassland"/>
  <tag k="type" v="multipolygon"/>
 </relation>

This is not the only entry where opening and closing tag doesn't match.

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.