commit 34870c7a1094904bc1c9202cea963ec0a355d732
parent 9d67f5b34c2c24c74cbe9af26ec24681f23b7481
Author: Tomas Hlavaty <tom@logand.com>
Date:   Thu, 13 Jun 2019 08:27:15 +0200
first try
Diffstat:
| A | Makefile |  |  | 8 | ++++++++ | 
| A | VERSION |  |  | 1 | + | 
| A | osmq |  |  | 10 | ++++++++++ | 
| A | osmtile.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;
+}