Git Product home page Git Product logo

geo's Introduction

Geo

At Factual, we process a lot of spatial data. We're open-sourcing one of our internal libraries for working with geospatial information, especially geohashes. We want all Clojure programmers to be able to answer questions about coordinates, distances, and polygon intersections. We think this library will be particularly useful in concert with our rich API of geospatial information.

We unify five open-source JVM geospatial libraries: The JTS topology suite, spatial4j, geohash-java, proj4j, and h3. Clojure protocols allow these libraries' disparate representations of points, shapes, and spatial reference systems to interoperate, so you can, for instance, ask whether a JTS point is within a geohash, whether a geohash intersects a spatial4j multipolygon, or whether a geohash's center point intersects with a JTS polygon projected in a local state plane.

In addition, we provide common scales and translation functions for unit conversion: converting between steradians and surface areas; finding the radius along the geoid, and some basic properties.

We hope that it can be a canonical resource for geospatial computation in Clojure.

Installation

Install via clojars

Clojars Project

Leiningen Dependency Vector:

[factual/geo "3.0.1"]

Documentation

Available on Github Pages here: http://factual.github.io/geo/3.0.1/index.html

Examples

; Load library
(require '[geo [geohash :as geohash] [jts :as jts] [spatial :as spatial] [io :as gio]])

; Find the earth's radius at the pole, in meters
user=> (spatial/earth-radius spatial/south-pole)
6356752.3

; Or at 45 degrees north
user=> (spatial/earth-radius (spatial/geohash-point 45 0))
6378137.0

; Distance between London Heathrow and LAX
user=> (def lhr (spatial/spatial4j-point 51.477500 -0.461388))
user=> (def lax (spatial/spatial4j-point 33.942495 -118.408067))
user=> (/ (spatial/distance lhr lax) 1000)
8780.16854531993 ; kilometers

; LHR falls within a 50km radius of downtown london
user=> (def london (spatial/spatial4j-point 51.5072 0.1275))
user=> (spatial/intersects? lhr (spatial/circle london 50000))
true

; But it's not in the downtown area
user=> (spatial/intersects? lhr (spatial/circle london 10000))
false

; At London, how many bits of geohash do we need for 100m features?
user=> (-> london (spatial/circle 50) geohash/shape->precision)
35

; Let's get the 35-bit geohash containing London's center:
user=> (def h (-> london (geohash/geohash 35)))
user=> h
#<GeoHash 1101000001000001000100100010101100000000000000000000000000000000 ->
(51.508026123046875,0.1263427734375) -> (51.50665283203125,0.127716064453125)
-> u10j4bs>

; How tall/fat is this geohash, through the middle?
user=> (geohash/geohash-midline-dimensions h)
[152.7895756415971 95.34671939564083]

; As a base32-encoded string, this hash is:
user=> (geohash/string h)
"u10j4bs"

; We can drop characters off a geohash to get strict supersets of that hash.
user=> (spatial/intersects? (geohash/geohash "u10j4") london)
true

; And we can show it's a strict superset by comparing the regions:
user=> (spatial/relate (geohash/geohash "u10j4bs") (geohash/geohash "u10j4"))
:within
user=> (spatial/relate (geohash/geohash "u10j4") (geohash/geohash "u10j4bs"))
:contains

; Versus, say, two adjacent hashes, which intersect along their edge
user=> (spatial/relate h (geohash/northern-neighbor h))
:intersects

; But two distant geohashes do *not* intersect
user=> (-> (iterate geohash/northern-neighbor h) (nth 5) (spatial/relate h))
:disjoint

; Find all 30-bit geohashes covering the 1km region around LHR
(-> lhr (spatial/circle 1000) (geohash/geohashes-intersecting 30) (->> (map geohash/string)))
("gcpsv3" "gcpsv4" "gcpsv5" "gcpsv6" "gcpsv7" "gcpsv9" "gcpsvd" "gcpsve" "gcpsvf" "gcpsvg" "gcpsvh" "gcpsvk" "gcpsvs" "gcpsvu")

; Or more directly
user=> (map geohash/string (geohash/geohashes-near lhr 1000 30))
("gcpsv3" "gcpsv4" "gcpsv5" "gcpsv6" "gcpsv7" "gcpsv9" "gcpsvd" "gcpsve" "gcpsvf" "gcpsvg" "gcpsvh" "gcpsvk" "gcpsvs" "gcpsvu")

; Reading JTS Geometries to/from common geo formats
user=> (gio/read-wkt "POLYGON ((-70 30, -70 30, -70 30, -70 30, -70 30))")
#object[org.locationtech.jts.geom.Polygon 0x675302a "POLYGON ((-70 30, -70 30, -70 30, -70 30, -70 30))"]

user=> (gio/to-wkt (gio/read-wkt "POLYGON ((-70 30, -70 31, -71 31, -71 30, -70 30))"))
"POLYGON ((-70 30, -70 31, -71 31, -71 30, -70 30))"


user=> (gio/read-geojson "{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[0.0,0.0]},\"properties\":{\"name\":\"null island\"}}")
({:properties {:name "null island"},
  :geometry   #object[org.locationtech.jts.geom.Point ... "POINT (0 0)"]})

user=> (->> "{\"type\":\"Polygon\",\"coordinates\":[[[-70.0,30.0],[-70.0,31.0],[-71.0,31.0],[-71.0,30.0],[-70.0,30.0]]]}"
            gio/read-geojson
            (map :geometry)
            (map gio/to-geojson))
("{\"type\":\"Polygon\",\"coordinates\":[[[-70.0,30.0],[-70.0,31.0],[-71.0,31.0],[-71.0,30.0],[-70.0,30.0]]]}")

user=> (gio/to-wkb (gio/read-wkt "POLYGON ((-70 30, -70 31, -71 31, -71 30, -70 30))"))
#object["[B" 0xe62e731 "[B@e62e731"]

user=> (gio/read-wkb *1)
#object[org.locationtech.jts.geom.Polygon 0x6f85711c "POLYGON ((-70 30, -70 31, -71 31, -71 30, -70 30))"]

Namespace overview

geo.spatial

Provides common interfaces for working with spatial objects and geodesics. All units are in meters/radians/steradians unless otherwise specified; coordinates are typically in long/lat "degrees" (which are not angular degrees). Provides static spatial contexts for the earth, and some constants like the earth's radii and circumferences, along with points like the poles.

Defines protocols for unified access to Points and Shapes, to allow different geometry libraries to interoperate.

Basic utility functions for unit conversion; e.g. degrees<->radians.

Functions for computing earth radii, surface distances, and surface areas.

Constructors for shapes like bounding-boxes and circles, and utility functions over shapes for their heights, centers, areas, etc. Can also compute relationships between shapes: their intersections, contains, disjoint statuses, etc.

geo.poly

Polygon operations: primarily intersection testing, point-contains, polygon->edges, bounding boxes, normal vectors, linear coordinates, bisections, box intersections, bounded-space partitioning, and so on.

geo.jts

Wrapper for the locationtech JTS spatial library. Constructors for points, coordinate sequences, rings, polygons, multipolygons, and so on.

Given a certain geometry, can transform using proj4j to a different coordinate reference system.

geo.geohash

Defines geohashes using the ch.hsr.geohash library, and extends them to support the Shapelike protocol; these geohashes can then interoperate with jts polygons and other shapes, and support the full range of shape and intersection queries.

Given a geohash, can find neighbors in each directions, and compute concentric square rings around that geohash. Extract centerpoints and dimensions, either via horizontal/vertical extent or estimated areas. Estimate errors for specific geohashes--error is largest at the equator and smallest at the poles. Round-trip geohashes to and from base32.

Given a target shape on the geoid, can tell you how many bits of precision are necessary to get geohashes on roughly that scale. Can compute all geohashes intersecting a shape in general, and all geohashes within a radius of a point in specific.

geo.io

Helper functions for dealing with common geospatial serialization formats. Use these to read and write from WKT, GeoJSON, WKB in byte and in hex string formats, and EWKB in byte and in hex string formats.

geo.crs

Helper functions for dealing with transforms between coordinate reference systems. Can create transformations used in the geo.jts namespace.

geo.h3

Defines hexagonal cells using the com.uber.h3 library. Extends H3's GeoCoord to support the Point protocol. H3 cells can be referenced either as strings or longs, and the corresponding Java functions will be called accordingly using the H3Index protocol.

Given a certain H3 cell, can compute surrounding rings, get the boundary in JTS format, or get the resolution.

Given a Shapelike geometry, can polyfill a list of H3 cells at a given level of resolution.

Given a list of H3 cells, can compact the list to remove redundant cells, uncompact the list to a desired resolution, or merge contiguous cells into a JTS multipolygon.

Given two different H3 cells, can get the grid distance between them.

Can create unidirectional edges based on different configurations of cells, and can check for the 12 pentagonal cells at each resolution.

IO functions return JTS Geometries.

Tests

The project uses Midje.

How to run the tests

lein midje will run all tests.

lein midje namespace.* will run only tests beginning with "namespace.".

lein midje :autotest will run all the tests indefinitely. It sets up a watcher on the code files. If they change, only the relevant tests will be run again.

Generating Codox Docs

  • Checkout appropriate release branch (e.g. release/2.0.0)
  • Generate docs with lein codox (This will generate the HTML/CSS/JS docs under target/doc)
  • Move generated docs out of target into appropriate dir under docs: mv target/doc/ docs/2.0.0
  • Commit changes, and merge that doc update to master

Updating deps.edn

While the project is based on leiningen, the use of depify can create a deps.edn file to enable a tools.deps.alpha-based development workflow. When dependencies in project.clj are updated, the deps.edn file can be updated manually or automatically. Based on depify's instructions, the command to update the deps.edn from the project root is:

clj -A:depify | clj -A:zprint > deps.edn.tmp ; mv deps.edn.tmp deps.edn

License

This project and many of its dependencies are licensed under the Eclipse Public License version 1.0.

geo's People

Contributors

aphyr avatar chen-factual avatar willcohen avatar wiseman avatar worace avatar zackteo avatar ztellman 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  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  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  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  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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geo's Issues

Intersecting geohashes at zero meridian, equator

Seems there is a problem around around the equator and the zero meridian:

(def factory (GeometryFactory. (PrecisionModel.) 4326))

(def geometry 
  (.toGeometry 
    factory 
    (Envelope. 2.0 6.0 42.0 48.0)))

(time (geohashes-intersecting geometry 10))
"Elapsed time: 1.296939 msecs"
=> (...)  

(def geometry 
  (.toGeometry 
    factory 
    (Envelope. -2.0 2.0 42.0 48.0)))

(time (geohashes-intersecting geometry 10))
; never finishes!

Or am I using the geohashes-intersecting function the wrong way?

2.0 Release

Heads up @chen-factual and @willcohen I think we're about ready for a final 2.0 release.

I have started a branch at https://github.com/Factual/geo/tree/release/2.0.0 which is what I'm hoping to release for that version. So any bugfixes or last minute things will need to get onto that branch. We have been using the 2.0.0-rc-3 version for a bit internally and so far it seems mostly good.

I'm hoping to merge @willcohen's H3 branch soon as well but am thinking we'll target that for a subsequent 2.1 release

bbox-geom provides no SRID

=> (require '[geo.geohash :as gh] '[geo.spatial :as sp])
nil
=> (sp/relate (gh/geohash "bcd") (gh/geohash "bcde"))
:contains
=> (sp/relate (gh/geohash "bcd") (gh/bbox-geom (gh/geohash "bcde")))

AssertionError Assert failed: Geometry must have a valid SRID to be transformed
(not= 0 geom-srid)  geo.jts/transform-geom (jts.clj:231)

README typo

In README: (geohash/sstring h) should be (geohash/string h)

to-geojson fail on a simple polygon

(require '[geo.io :as gio])
=> nil

; read-wkt is ok 
(gio/read-wkt "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))")
=> #object[org.locationtech.jts.geom.Polygon 0x223e81a9 "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"]

; issue and exception thrown
(gio/to-geojson (gio/read-wkt "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"))
Execution error (NoSuchMethodError) at org.wololo.jts2geojson.GeoJSONWriter/convert (GeoJSONWriter.java:79).
'org.locationtech.jts.geom.LineString org.locationtech.jts.geom.Polygon.getExteriorRing()'

Simple fix is perhaps by updating libraries:
locationtech/spatial4j#192

Optimize geohash/geohashes-intersecting faster

It takes ~5 minutes on a beefy machine to split the US polygon into 778 L3 geohashes. This seems a bit ridiculous.

Profiling the job, I see we're burning 92% of compute time in org.locationtech.spatial4j.shape.jts.JtsShapeFactory.makeShape(), so looking at how we can reduce calls there seems like an obvious place to optimize.

Support specifying precision for geo.io write functions

Hi there, thanks for this cool and useful library. I was just wondering what you all think of the idea of being able to specify a number of decimal places for coordinates for the various to-<format> functions. I find using this library so much nicer than working e.g. geotools or other java libraries in my clojure projects, but one thing I miss is being able to sneak in rounding coordinates whilst converting between formats, e.g. using geotools libs I used to do:

(->> wkt-literal
     (.read (WKTReader2.))
     (.toString (GeometryJSON. 6)))

(where that 6 is the number of decimals to use when encoding the numbers)

I find this much nicer with this library (e.g. (-> wkt-literal geoio/read-wkt geoio/to-geojson)), but to get identical results I need to add an extra transformation step to round all the coordinates. This isn't really a big deal, but I wanted too see what you think of adding a second arity to the to-<format> functions in this library to support this. I could possibly help out with a PR for that if it's something you think is reasonable. I also totally understand if there are reasons why this is a bad idea and you don't want it in.

Consider enabling *warn-on-reflection*

Clojure reflection eats up a surprising amount of execution time. I see a lot of type-hinting in the codebase here, which tells me we care about compute times.

A simple example:

(facts "benchmark linestring"
       (time
        (dotimes [_ 100000]
          (linestring [(coordinate 30 70) (coordinate 31 71)] 4326))))

Master: "Elapsed time: 272.940221 msecs"
With exhaustive type hinting: "Elapsed time: 34.371557 msecs"

I have sample code on feature/type-hints.

Geometry transformations

@worace Per the comment in the merge of #6, if you're considering doing a bump to 2.0, then I would suggest holding off until considering integrating transformations between projections. It shouldn't change the actual API but might change assumptions about treating the geometries themselves. The JTS objects you're currently constructing all say they are WGS84 already, so it should logically fit in nicely to correctly work with JTS objects that have different SRIDs and allow the library to work between them as needed.

proj4j is what I'd use to do this, though development since its last release has moved to a locationtech repository and releases will probably be from there once they get their IP due diligence worked out. In the meantime, geotrellis maintains a fork of proj4j that fixes bugs since 0.1.0 and is what the newer locationtech version will be based on.

Documentation was a bit confusing

I'm not a GIS guru, I'm just posting this to provide some feedback on the documentation. (the struggles of a beginner)

This is just for reference and in case anyone else stubs their toes. Or if I forget how to do this and need to look back later :)
Feel free to close this issue

For background:

I took the world shorelines from

https://www.ngdc.noaa.gov/mgg/shorelines/

I converted it to a GeoJSON using ogr2ogr

gr2ogr -f GeoJSON shoreline.json GSHHS_c_L1.shp 

I then read it into Clojure with

(-> "/path-to-my-file/shoreline.json"
    slurp
    read-geojson)

So far so good :)

I then want to cut down these shoreline polygons to a certain lat-long region of interest. (I will later convert this to an SVG). So I try to create a polygon and then intersect it with my shoreline

And this is where things get hairy. I try to create a polygon

http://factual.github.io/geo/3.0.1/geo.jts.html#var-polygon

the docs read

(polygon shell)
(polygon shell holes)

Given a LinearRing shell, and a list of LinearRing holes, generates a
polygon.

Okay, so to make a polygon I need to first make a LinearRing. I looke up the docs for that: http://factual.github.io/geo/3.0.1/geo.jts.html#var-linear-ring

linear-ring
(linear-ring coordinates)
(linear-ring coordinates srid)

Given a list of Coordinates, creates a LinearRing. Allows an optional SRID argument at end.

Okay so to make a linear ring I need to make a Coordinates ... I look up that: http://factual.github.io/geo/3.0.1/geo.jts.html#var-coordinates

coordinates
(coordinates geom)

Get a sequence of Coordinates from a Geometry

Now i'm way down the rabbit hole, but there is no geometry

There are two similar things

geometries
(geometries c)

Given a GeometryCollection, generate a sequence of Geometries

and

geometry-collection
(geometry-collection geometries)

Given a list of Geometries, generates a GeometryCollection.

But as you can see they reference each other in their arguments


So it turns out that when it says (linear-ring coordinates) the docs read "Given a list of Coordinates ..." what this expects is an actual Clojure seq with coordinates.

First I tried to do

(linear-ring [ (coordinate 0 0) (coordinate 0 75) (coordinate 75 75) (coordinate 75 0) ])

And I got an error. Turns out you need to make sure the last point is equal to the first

So this works

(linear-ring [ (coordinate 0 0) (coordinate 0 50) (coordinate 50 50) (coordinate 50 0)  (coordinate 0 0) ]

Now that I've made a polygon I can intersect it

Putting it all together I got this:

  (let [shoreline   (-> "/my-path-to-shoreline-file/shoreline.json"
			slurp
			read-geojson)
	area-of-interest (polygon (linear-ring [(coordinate 0 0)
						(coordinate 0 50)
						(coordinate 50 50)
						(coordinate 50 0)
						(coordinate 0 0) ]))]
    (->> shoreline
	 (map (fn [shoreline-poly]
		(update shoreline-poly
			:geometry
			#(intersection %
				       area-of-interest))))
	  (filter #(not (.isEmpty (:geometry %))))
	 to-geojson-feature-collection
	 (spit "trimmed-shorelines.json")))

And to my surprise trimmed-shorelines.json opens up in QGIS. And it even looks correct!

(Please let me know if I'm not doing this in the way the library expects me to :) )

The only caveat is that at certain "clip" sizes I'd get two layers in the GeoJSON for some reason. Most would be Polygons and once in a while I'd get GeometryCollection. My best guess is one of the intersections split a (concave) polygon into multiple smaller polygons and this gets crammed into a single collection.

If my guess is right then I imagine with some fiddling you could probably duplicate the Shapelike that has the GeometryCollection and copy out each Polygon to flatten the whole thing - so that you only have Shapelike's with polygons


I haven't done the Polygon to SVG conversion yet. I'm not super clear on how the library expects me to extract coordinates. The only way I see for now is to dip into JTS. It's a tad ugly but it seems to work.

  (let [shoreline   (-> "/home/geokon/Downloads/coast/GSHHS_shp/c/shoreline.json"
			slurp
			read-geojson)
	area-of-interest (polygon (linear-ring [(coordinate 0 0)
						(coordinate 0 50)
						(coordinate 50 50)
						(coordinate 50 0)
						(coordinate 0 0) ]))]
      (->> shoreline
	   (map (fn [shoreline-poly]
		  (update shoreline-poly
			  :geometry
			  #(intersection %
					 area-of-interest))))
	   (filter #(not (.isEmpty %)))
	 (map :geometry)
	 (map coordinates)
	 (map coord-array) 
	 (map (fn [poly]
		(map #(vector (.getX %)
			      (.getY %))
		     poly)))

Please let me know if there is something more kosher

Once I get a basic plotting/display pipeline going I'll post an update. Thanks for the library guys! It's going way smoother than I anticipated (my only hangup really was how to read in shapefiles)

3.0 Release

@worace are there any other changes you think would make sense for 3.0? Is it a good idea to get a first alpha out that uses all the updated dependencies?

H3 as hex alternative to geohash?

Do you have interest in including support for h3 (java here) as a hexagonal alternative alongside geohashes?
Hex grids are one of the spatial operations where I’m currently dropping down to postgis, and the hierarchical structure of these is pretty neat. If so, happy to take a stab at initial support — there’s a lot of functions in there with parallels to some of this library’s geohash functions, but might be good to start with adding it to shapelike, getting points in and out, and taking it from there.

Clojurescript support

Before I embark on what would be a very large pull request, I thought I'd first check in with you all on whether it makes sense. Today's Clojurescript release contains functionality which, I think, finally enables the ability to port geo to Clojurescript.

There are already javascript analogues to most of the functionality in here on the java side: jsts, proj4js, h3-js, and so on. I've already gotten proj4js mostly working, transforming the full list of projections already available to geo through proj4j. All of the interop issues between java spatial libraries apply just as much to javascript, so I think this would be similarly valuable, and having the syntax work similarly between platforms seems very very useful. As I keep working on libraries that build on top of geo, it'd open all of them up to working cross-platform too, with (hopefully) fairly low cljc syntax needed later on.

This would, though, be a big change to geo. It wouldn't change any of the existing library, but I'd need to add a bunch of .cljc logic whenever things drop down to java, which is often, or whenever functionality between java and javascript aren't quite the same. Similarly, this would probably require moving away from midje and to clojure.test, which allows for cross compatibility with cljs.test.

If this seems within the scope of this library, how would it sound for me to start working on a PR in a new branch?

@worace

converting from CRS 7405

Hi there
I am trying out your library as a way of converting from CRS 7405 (BNG 3D) into wgs84. As there wasn't any docs examples I started at the tests to see if there were code snippets I could use as examples there.

This led to some confusion as the code used there turns out to be unreleased (once I found this info in the changelog it became a lot clearer)

I'm getting further now that I'm using the previous jts/gf but just noting here in case you could provide examples for this based on the currently released codebase (or keep unreleased code on a different branch or something, going forward)

Thanks for the library it's great to have so many useful functions in one place!

Support for H3 version 4+

Update geo to support for H3

The H3 library introduced breaking changes in version 4.0.0, so applications developed against earlier versions need to be updated before they can use the new library version. Most of the changes relate to function naming, and some relate to the behavior of the functions.

https://h3geo.org/docs/next/library/migrating-3.x/

Possible issue: link error when loading geo in repl

Not sure if this is an issue yet or not...
I develop and test on MacOS, no problems....
I am currently in the process of deploying to a FreeBSD server, and when I attempt (from lein repl):

(use 'tcr.process)
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Execution error (UnsatisfiedLinkError) at java.lang.ClassLoader$NativeLibrary/load (ClassLoader.java:-2).
/tmp/libh3-java8969621080322806083.so: Shared object "libm.so.6" not found, required by "libh3-java8969621080322806083.so"

I'm attempting to debug this at the moment, and will revise and/or provide more info as I get it...
Obviously this could be some sort of setup, configuration, or environment issue on my side...

lein repl
nREPL server started on port 47259 on host 127.0.0.1 - nrepl://127.0.0.1:47259
REPL-y 0.4.3, nREPL 0.6.0
Clojure 1.10.1
OpenJDK 64-Bit Server VM 1.8.0_222-b10

io/to-geojson throwing error from io/read-wkt

Hi friends,

Converting a wkt file to geojson using:

(-> wkt-obj
    geo.io/read-wkt ; works fine
    geo.io/to-geojson) ; fails here

and to-geojson is throwing the following error:

NoSuchMethodError com.fasterxml.jackson.databind.JavaType.isReferenceType()Z  com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2 (BeanSerializerFactory.java:205)

I saw some things about jackson deps mismatch in my search, but was wondering if you guys had any other ideas.

Cheers,

to-geojson and parse-geojson don't compose

It would be nice if we could easily convert between formats using geo.io. I'm trying to convert GeoJSON to WKT.

(geo-io/to-wkt (geo-io/parse-geojson geojson-point))

throws

No implementation of method: :to-jts of protocol: #'geo.spatial/Shapelike found for class: org.wololo.geojson.Point

The same is thrown even if I try to round-trip from and to geojson:

(geo-io/to-geojson (geo-io/parse-geojson geojson-point))

io/read-geojson throws error

(-> (slurp "https://gist.githubusercontent.com/heyarne/09812024067c4db239df2181c347f743/raw/a9a372710097e4d2c3df699e3b84cdfd1526eb7e/isochrones-galton-lat:52.5219184-lng:13.4132147.geojson")
  (io/read-geojson))

throws the following exception:

Exception thrown: java.lang.NoSuchMethodError (com.fasterxml.jackson.databind.JavaType.isReferenceType()Z)

    _createDeserializer2 - (DeserializerCache.java:397)
    _createDeserializer - (DeserializerCache.java:349)
    _createAndCache2 - (DeserializerCache.java:264)
    _createAndCacheValueDeserializer - (DeserializerCache.java:244)
    findValueDeserializer - (DeserializerCache.java:142)
    findRootValueDeserializer - (DeserializationContext.java:476)
    _findRootDeserializer - (ObjectMapper.java:3899)
    _readMapAndClose - (ObjectMapper.java:3794)
    readTree - (ObjectMapper.java:2381)
    create - (GeoJSONFactory.java:21)
    read - (GeoJSONReader.java:16)
    read-geojson - geo.io - (io.clj:23)
    read-geojson - geo.io - (io.clj:23)
    eval12767 - rbb-data.gorilla.map-view - (form-init8373600070398405018.clj:1)
    eval12767 - rbb-data.gorilla.map-view - (form-init8373600070398405018.clj:1)

My project.clj:

(defproject not-important "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [factual/geo "1.2.0"]
                 [dk.ative/docjure "1.12.0"]]
  :plugins [[lein-gorilla "0.4.0"]]
  :main ^:skip-aot not-important.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

Environment info:

❯ system_profiler SPSoftwareDataType
Software:

    System Software Overview:

      System Version: macOS 10.13.4 (17E199)
      Kernel Version: Darwin 17.5.0
      Boot Volume: Macintosh HD
      Boot Mode: Normal

❯ java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

Extend Point to convert to JTS?

Since geo.io requires JTS geometries, I don't think it's possible to do things like write a geohash-center's point to wkt or geojson using existing functions, since there's no way to cast it to Geometry without pulling out coordinates manually and making a new point. How do you feel about extending the Point protocol to include (to-jts-point)?

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.