Skip to content

Commit

Permalink
add importer, update metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
yetzt committed Nov 24, 2024
1 parent c016211 commit c305ea7
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/data
/node_modules
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ This repository contains the shapes of german postcode areas (Postleitzahlengebi

## Data

* [GeoJSON, Brotli Compressed](https://github.com/yetzt/postleitzahlen/releases/download/2024.09/postleitzahlen.geojson.br) (18MB)
* [TopoJSON, Brotli Compressed](https://github.com/yetzt/postleitzahlen/releases/download/2024.09/data/postleitzahlen.topojson.br) (11MB)
* [GeoJSON, Brotli Compressed](https://github.com/yetzt/postleitzahlen/releases/download/2024.11/postleitzahlen.geojson.br) (30.22MB)
* [TopoJSON, Brotli Compressed](https://github.com/yetzt/postleitzahlen/releases/download/2024.11/data/postleitzahlen.topojson.br) (20.75MB)

## Source

Expand All @@ -21,6 +21,11 @@ area[wikidata="Q183"]->.searchArea;
);
out body geom;
```

## Importer

Included in this repository is the import script used to generate the data files: `sh bin/import.sh`

## Alternatives

* [Postleitzahlen-Scraper](https://github.com/yetzt/postleitzahlen-scraper) - A program that downloads non-free postcode geometries from the german postal service.
Expand Down
47 changes: 47 additions & 0 deletions bin/import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

const fs = require("node:fs/promises");
const path = require("node:path");

const src = path.resolve(__dirname, "../data/postleitzahlen.raw.geojson");
const srcBuesingen = path.resolve(__dirname, "../data/buesingen.raw.geojson");
const dest = path.resolve(__dirname, "../data/postleitzahlen.geojson");

// recursive round
function recursiveRound(a){
return (a instanceof Array) ? a.map(b=>recursiveRound(b)) : (Math.round(a*1e6)/1e6);
};

(async()=>{

// geojson template
const geojson = {
"type": "FeatureCollection",
"copyright": "© OpenStreetMap contributors, https://openstreetmap.org/copyright",
"timestamp": (new Date()).toISOString(),
"features": []
};

// add features from source
geojson.features = JSON.parse(await fs.readFile(src)).features;
geojson.features.push(JSON.parse(await fs.readFile(srcBuesingen)).features.pop());

// edit features
geojson.features = geojson.features.map(f=>{

// round geometry
f.geometry.coordinates = recursiveRound(f.geometry.coordinates);

// properties
f.properties = {
postcode: f.properties.postal_code,
rel: f.properties.id.split("/").pop(),
};

return f;

}).sort((a,b)=>a.properties.postcode.localeCompare(b.properties.postcode)); // sort

// write
await fs.writeFile(dest, JSON.stringify(geojson));

})();
82 changes: 82 additions & 0 deletions bin/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/sh

# change to script dir
cd "$( dirname $0 )/..";
APPDIR=$( pwd -P )

# load nvm node if not vailable
if [ ! `command -v node` ] && [ -f "$HOME/.nvm/nvm.sh" ]; then
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh";
if [ ! `command -v node` ]; then
prnt "Missing node ( https://nodejs.org/en/download/package-manager )";
exit 1;
fi;
fi;

# check npm
if [ ! `command -v npm` ]; then
prnt "Missing npm ( https://github.com/npm/cli/releases )";
exit 1;
fi;

# check osmtogeojson
if [ ! `command -v osmtogeojson` ]; then
npm i -g osmtogeojson;
if [ ! `command -v osmtogeojson` ]; then
prnt "Missing osmtogeojson (npm i -g osmtogeojson)";
exit 1;
fi;
fi;

# check geo2topo
if [ ! `command -v geo2topo` ]; then
npm i -g topojson-server;
if [ ! `command -v geo2topo` ]; then
prnt "Missing geo2topo (npm i -g topojson-server)";
exit 1;
fi;
fi;

if [ ! `command -v curl` ]; then
prnt "Missing curl ( https://curl.se/download.html )";
exit 1;
fi;

# get postcodes from overpass; buesingen is not included in the first query and has to be requested separately
echo "Fetching Postcode Areas";
curl -v -G "http://overpass-api.de/api/interpreter" --data "data=%5Bout%3Ajson%5D%3B%20area%5Bwikidata%3D%22Q183%22%5D-%3E.searchArea%3B%20(%20relation%5B%22type%22%3D%22boundary%22%5D%5B%22boundary%22%3D%22postal_code%22%5D(area.searchArea)%3B%20)%3B%20out%20body%20geom%3B" > "$APPDIR/data/postleitzahlen.osm.json";
curl -v -G "http://overpass-api.de/api/interpreter" --data "data=%5Bout%3Ajson%5D%3B%20relation%5B%22type%22%3D%22boundary%22%5D%5B%22boundary%22%3D%22postal_code%22%5D%5B%22postal_code%22%3D%2278266%22%5D%3B%20out%20body%20geom%3B" > "$APPDIR/data/buesingen.osm.json";

# convert to geojson
echo "Converting to GeoJSON";
osmtogeojson -m "$APPDIR/data/postleitzahlen.osm.json" > "$APPDIR/data/postleitzahlen.raw.geojson";
osmtogeojson -m "$APPDIR/data/buesingen.osm.json" > "$APPDIR/data/buesingen.raw.geojson";

# import
echo "Importing";
node "$APPDIR/bin/import.js";

# convert to topojson
geo2topo "$APPDIR/data/postleitzahlen.geojson" > "$APPDIR/data/postleitzahlen.topojson";

# compress
echo "Compressing";
if [ `command -v brotli` ]; then
brotli -k9 "$APPDIR/data/postleitzahlen.geojson";
brotli -k9 "$APPDIR/data/postleitzahlen.topojson";
fi;

echo "Clean Up";
rm -f "$APPDIR/data/buesingen.osm.json";
rm -f "$APPDIR/data/buesingen.raw.geojson";
rm -f "$APPDIR/data/postleitzahlen.osm.json";
rm -f "$APPDIR/data/postleitzahlen.raw.geojson";

# delete uncompressed files only if compressed
if [ -e "$APPDIR/data/postleitzahlen.geojson.br" ]; then
rm -f "$APPDIR/data/postleitzahlen.geojson";
fi;
if [ -e "$APPDIR/data/postleitzahlen.topojson.br" ]; then
rm -f "$APPDIR/data/postleitzahlen.topojson";
fi;
2 changes: 1 addition & 1 deletion datapackage.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name" : "postleitzahlen-de",
"version": "1.0.4",
"version": "1.0.5",
"title" : "Postleitzahlen Deutschland",
"description": "german postcode areas 2024",
"license": "ODbL-1.0",
Expand Down
2 changes: 1 addition & 1 deletion opendata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "postleitzahlen-de",
"version": "1.0.4",
"version": "1.0.5",
"description": "german postcode areas 2024",
"license": "ODbL-1.0",
"files": [
Expand Down
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"private": true,
"name": "postleitzahlen",
"version": "1.0.0",
"main": "bin/import.js",
"author": "yetzt <[email protected]>",
"license": "Unlicense",
"description": "import german postcode areas from osm via overpass",
"dependencies": {}
}

0 comments on commit c305ea7

Please sign in to comment.