osmq

openstreetmap for command line
git clone https://logand.com/git/osmq.git/
Log | Files | Refs

commit 34870c7a1094904bc1c9202cea963ec0a355d732
parent 9d67f5b34c2c24c74cbe9af26ec24681f23b7481
Author: Tomas Hlavaty <tom@logand.com>
Date:   Thu, 13 Jun 2019 08:27:15 +0200

first try

Diffstat:
AMakefile | 8++++++++
AVERSION | 1+
Aosmq | 10++++++++++
Aosmtile.c | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 172 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,8 @@ +all: osmtile + +osmtile: osmtile.c + $(CC) -Wall -Os -o $@ $< -lm + strip $@ + +clean: + rm osmtile diff --git a/VERSION b/VERSION @@ -0,0 +1 @@ +"0.1" diff --git a/osmq b/osmq @@ -0,0 +1,10 @@ +#!${bash}/bin/bash +set -e +set -o pipefail +curl \ + -s \ + "https://nominatim.openstreetmap.org/search?q=$*&format=json" \ + | jq \ + -r \ + 'map([.lat, .lon, .display_name] | join(", ")) | join("\n")' \ + | fzf -0 -1 --with-nth=3.. diff --git a/osmtile.c b/osmtile.c @@ -0,0 +1,153 @@ +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames */ +static int long2tilex(double lon, int z) { + return (int)(floor((lon + 180.0) / 360.0 * pow(2.0, z))); +} + +static int lat2tiley(double lat, int z) { + return (int)(floor((1.0 - log(tan(lat * M_PI/180.0) + 1.0 / cos(lat * M_PI/180.0)) / M_PI) / 2.0 * pow(2.0, z))); +} + +static double tilex2long(int x, int z) { + return x / pow(2.0, z) * 360.0 - 180; +} + +static double tiley2lat(int y, int z) { + double n = M_PI - 2.0 * M_PI * y / pow(2.0, z); + return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); +} + +static int zoom(char *string) { + int z; + if(!string) goto fail; + if(1 != sscanf(string, "%d", &z)) goto fail; + if(z < 0 || 18 < z) goto fail; + return z; + fail: + fprintf(stderr, "expected zoom 0 <= %s <= 18\n", string); + exit(1); +} + +static int lat(int argc, char *argv[]) { + int z = zoom(argv[0]); + char *value = argv[1]; + if(!value) goto fail; + int y; + if(1 != sscanf(value, "%d", &y)) goto fail; + printf("%lf\n", tiley2lat(y, z)); + return 0; + fail: + fprintf(stderr, "unexpected y %s\n", value); + return 1; +} + +static int lon(int argc, char *argv[]) { + int z = zoom(argv[0]); + char *value = argv[1]; + if(!value) goto fail; + int x; + if(1 != sscanf(value, "%d", &x)) goto fail; + printf("%lf\n", tilex2long(x, z)); + return 0; + fail: + fprintf(stderr, "unexpected x %s\n", value); + return 1; +} + +static int x(int argc, char *argv[]) { + int z = zoom(argv[0]); + char *value = argv[1]; + if(!value) goto fail; + double lon; + if(1 != sscanf(value, "%lf", &lon)) goto fail; + printf("%d\n", long2tilex(lon, z)); + return 0; + fail: + fprintf(stderr, "unexpected longitude %s\n", value); + return 1; +} + +static int y(int argc, char *argv[]) { + int z = zoom(argv[0]); + char *value = argv[1]; + if(!value) goto fail; + double lat; + if(1 != sscanf(value, "%lf", &lat)) goto fail; + printf("%d\n", lat2tiley(lat, z)); + return 0; + fail: + fprintf(stderr, "unexpected latitude %s\n", value); + return 1; +} + +static int url(int argc, char *argv[]) { + int z = zoom(argv[0]); + double lat; + if(1 != scanf("%lf", &lat)) { + fprintf(stderr, "expected latitude\n"); + return 1; + } + char skip[1024]; + if(1 != scanf("%1023[ ,]", skip)) { + fprintf(stderr, "expected separator\n"); + return 1; + } + double lon; + if(1 != scanf("%lf", &lon)) { + fprintf(stderr, "expected longitude\n"); + return 1; + } + int x = long2tilex(lon, z); + int y = lat2tiley(lat, z); + printf("https://tile.openstreetmap.org/%d/%d/%d.png\n", z, x, y); + return 0; +} + +static int version(int argc, char *argv[]) { + printf("%s\n", +#include "VERSION" + ); + return 0; +} + +static int help(int argc, char *argv[]) { + printf("usage: osmtile cmd args\n"); + printf(" lat zoom y\n"); + printf(" lon zoom x\n"); + printf(" x zoom longitude\n"); + printf(" y zoom latitude\n"); + printf(" url zoom\n"); + printf(" --version\n"); + printf(" --help\n"); + return 0; +} + +int main(int argc, char *argv[]) { + char *cmd = argv[1]; + if(!cmd) goto fail; + static const struct { + char *cmd; + int (*fn)(int argc, char *argv[]); + } dispatch[] = { + {"lat", lat}, + {"lon", lon}, + {"x", x}, + {"y", y}, + {"url", url}, + {"--version", version}, + {"--help", help}, + {NULL} + }; + for(int i = 0; dispatch[i].cmd; i++) { + if(!strcmp(dispatch[i].cmd, cmd)) { + return dispatch[i].fn(argc - 2, &argv[2]); + } + } + fail: + fprintf(stderr, "unexpected command %s\n", cmd); + return 1; +}