-
Notifications
You must be signed in to change notification settings - Fork 17
/
crs.clj
78 lines (64 loc) · 2.25 KB
/
crs.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
(ns geo.crs
"Helper functions for identifying and manipulating Coordinate Reference Systems."
(:import (org.osgeo.proj4j CoordinateTransform
CoordinateTransformFactory
CRSFactory)))
(defn starts-with? [string prefix]
(.startsWith string prefix))
(defn includes? [string substring]
(.contains string substring))
(def epsg-str? (partial re-matches #"EPSG:(\d+)"))
(def srid->epsg-str
"Convert an SRID integer to EPSG string."
(partial str "EPSG:"))
(defn epsg-str->srid
"Converts EPSG string to SRID, if possible."
[epsg]
(let [match (epsg-str? epsg)]
(assert match "Must be a valid EPSG string")
(Integer/parseInt (last match))))
(def ^CoordinateTransformFactory ctf-factory
(CoordinateTransformFactory.))
(def ^CRSFactory crs-factory
(CRSFactory.))
(def valid-crs-prefixes ["EPSG" "ESRI" "NAD83" "NAD27" "WORLD"])
(defn crs-name?
"Check if input is a valid CRS name accepted by proj4j.
Accepted CRS names are in the forms:
EPSG:xxxx, ESRI:xxxx, NAD83:xxxx, NAD27:xxx, or WORLD:xxxx."
[crs-str]
(some (fn [prefix] (starts-with? crs-str (str prefix ":")))
valid-crs-prefixes))
(defn proj4-string?
"Check if input appears to be a proj4 string"
[crs-str]
(includes? crs-str "+proj="))
(defn- create-crs-int
[^Integer c]
(.createFromName crs-factory (srid->epsg-str c)))
(defn- create-crs-name
[^String c]
(.createFromName crs-factory c))
(defn- create-crs-parameters
[^String c]
(.createFromParameters crs-factory "" c))
(defn- create-crs
"Create a CRS system. If given an integer, assume it is an EPSG code.
If given a valid CRS name or proj4 string, use that as the CRS identifier."
[c]
(cond (integer? c)
(create-crs-int c)
(crs-name? c)
(create-crs-name c)
(proj4-string? c)
(create-crs-parameters c)))
(defn ^CoordinateTransform create-transform
"Creates a proj4j transform between two projection systems.
c1 or c2 can be:
- integers (which will be interpreted as that EPSG)
- a string identifier for types EPSG:XXXX, ESRI:XXXX, WORLD:XXXX, NAD83:XXXX, or NAD27:XXXX
- proj4 string."
[c1 c2]
(.createTransform ctf-factory
(create-crs c1)
(create-crs c2)))