LocationTech Spatial4j: A Geospatial Library for Java

Related tags

Geospatial spatial4j
Overview

Spatial4j

Build Coverage Maven

(note: Spatial4j's official home page is at LocationTech: https://projects.eclipse.org/projects/locationtech.spatial4j but this README has richer information)

Spatial4j is a general purpose spatial / geospatial ASL licensed open-source Java library. It's core capabilities are 3-fold: to provide common shapes that can work in Euclidean and geodesic (surface of sphere) world models, to provide distance calculations and other math, and to read & write shapes from formats like WKT and GeoJSON. Spatial4j is a project of the LocationTech Industry Working Group of the Eclipse Foundation.

If you are working with spatial grid-square indexing schemes, be it Geohash or something custom, then you are likely to find especially high utility from Spatial4j.

Spatial4j is well tested; it's monitored via Travis-CI continuous integration (plus another Hudson build) and we use Codecov for code coverage.

If you are interested in contributing to Spatial4j please review the contribution guidelines.

Shapes and Other Features

The main part of Spatial4j is its collection of shapes. Shapes in Spatial4j have these features:

  • Compute its lat-lon bounding box.
  • Compute an area. For some shapes its more of an estimate.
  • Compute if it contains a provided point.
  • Compute the relationship to a lat-lon rectangle. Relationships are: CONTAINS, WITHIN, DISJOINT, INTERSECTS. Note that Spatial4j doesn't have a notion of "touching".

Spatial4j has a variety of shapes that operate in Euclidean-space -- i.e. a flat 2D plane. Most shapes are augmented to support a wrap-around at X -180/+180 for compatibility with latitude & longitudes, which is effectively a cylindrical model. But the real bonus is its circle (i.e. point-radius shape that can operate on a surface-of-a-sphere model. See below for further info. The term "geodetic" or "geodesic" or "geo" is used here as synonymous with that model but technically those words have a more broad meaning.

Shape Euclidean Cylindrical Spherical
Point Y Y Y
Rectangle Y Y Y
Circle Y N Y
LineString Y N N
Buffered L/S Y N N
Polygon Y Y N
ShapeCollection Y Y Y
  • The Rectangle shape exists in the spherical model as a lat-lon rectangle, which basically means it's math is no different than cylindrical.
  • Polygons don't support pole-wrap (sorry, no Antarctica polygon); just dateline-cross. Polygons are supported by wrapping JTS's Geometry, which is to say that most of the fundamental logic for that shape is implemented by JTS.

Other Features

  • Read and write Shapes as WKT. Include the ENVELOPE extension from CQL, plus a Spatial4j custom BUFFER operation. Buffering a point gets you a Circle.
  • Read and write Shapes as GeoJSON.
  • Read and write Shapes as Polyshape.
  • Read and write Shapes using the Jackson-databdind serialization framework.
  • 3 great-circle distance calculators: Law of Cosines, Haversine, Vincenty

For more information on the formats supported, see FORMATS.md.

Dependencies

Spatial4j runs on Java 8 (v1.8) or better. Otherwise, all dependencies listed in the maven pom.xml are either marked optional or are for testing. The optional dependencies are:

  • JTS: You need JTS if you use polygons, or obviously if you use any of the classes prefixed with "Jts".
  • Noggit: The Noggit JSON parsing library is only needed for GeoJSON parsing (not required for writing).
  • Jackson-databind: If you wish to use Spatial4j's Jackson-databind feature to read/write shapes.

Why not use JTS? Why should you use Spatial4j?

Spatial4j was born out of an unmet need from other open-source Java software.

JTS is the most popular spatial library in Java. JTS is powerful but it only supports Euclidean geometry (no geodesics) and it has no Circle shape. Spatial4j has a geodesic circle implementation, and it wraps JTS geometries to add dateline-wrap support (no pole wrap yet). JTS recently broadened it's licensing but originally this was a major factor contributing to the founding of Spatial4j.

A geodesic circle implementation (i.e. point-radius on surface of a sphere), has been non-trivial; see for yourself and look at the extensive testing. Presumably many applications will use a polygon substitute for a circle, however note that not only is it an approximation, but common algorithms inscribe instead of circumscribe the circle. The result is a polygon that doesn't quite completely cover the intended shape, potentially resulting in not finding desired data when applied to the information-retrieval domain (e.g. indexing/search in Apache Lucene) where it is usually better to find a false match versus not find a positive match when making approximations. Also, Spatial4j's implementation goes to some lengths to be efficient by only calculating the great-circle-distance a minimum number of times in order to find the intersection relationship with a rectangle. Even computing the bounding-box of this shape was non-obvious, as the initial algorithm lifted from the web at a popular site turned out to be false.

Getting Started

Javadoc API

The facade to all of Spatial4j is the SpatialContext. It acts as a factory for shapes and it holds references to most other classes you might use and/or it has convenience methods for them. For example you can get a DistanceCalculator but if you just want to calculate the distance then the context has a method for that.

To get a SpatialContext (or just "context" for short), you could use a global singleton SpatialContext.GEO or JtsSpatialContext.GEO which both use geodesic surface-of-sphere calculations (when available); the JTS one principally adds Polygon support. If you want a non-geodesic implementation or you want to customize one of many options, then instantiate a SpatialContextFactory (or JtsSpatialContextFactory), set the options, then invoke newSpatialContext(). If you have a set of name-value string pairs, perhaps from a java properties file, then instead use the static makeSpatialContext(map, classLoader) method which adds a lot of flexibility to the configuration initialization versus hard-coding it.

You should generally avoid calling constructors for anything in Spatial4j except for the SpatialContextFactory. Constructors aren't strictly forbidden but the factories are there to provide an extension point / abstraction, so don't side-step them unless there's a deliberate reason.

Miscellaneous

Discuss Spatial4j on our mailing list (note: old list is here).

View metadata about the project as generated by Maven: maven site.

Spatial4j has been ported to .NET (C#) where it is appropriately named Spatial4n.

Future Road Map Ideas

  • Support for projections by incorporating Proj4j
  • More surface-of-sphere implemented shapes (LineString, Polygon), such as by using Geo3D
  • Polygon pole wrap
  • Multi-dimensional?

History

Before Spatial4j, there was Lucene Spatial Playground (LSP) and from this work a generic core spatial library emerged, independent of Lucene: Spatial4j. The other parts of LSP were either merged into Lucene / Solr itself or were migrated to Spatial Solr Sandbox.
On February 26th 2016, with release 0.6, Spatial4j became a LocationTech project (a part of Eclipse) following a long incubation period.

Comments
  • ShapeFactory and some builders

    ShapeFactory and some builders

    This moves shape construction from SpatialContext to a new ShapeFactory interface. And it formalizes polygon construction and other shapes without requiring JTS.

    opened by dsmiley 15
  • Comparing a vertical Rectangle at +180 and -180 is sometimes wrong

    Comparing a vertical Rectangle at +180 and -180 is sometimes wrong

    Rectangle.relate(Rectangle) reports INTERSECTS in this case when the actual result should be either DISJOINT or preferably whatever the Y dimension reports when it's WITHIN or CONTAINS | :

    This fails: assertRelation(WITHIN, ctx.makeRectangle(-180, -180, -10, 10), ctx.makeRectangle(180, 180, -30, 30)); The existing tests normalize rects, and so this wasn't found.

    bug 
    opened by dsmiley 15
  • add support for jackson serialization

    add support for jackson serialization

    Here is a quick sketch for how to do that. This requires changing the project structure so that we can have multiple .jar files

    NOTE: this is not ready to commit -- but want early feedback to see if the direction is OK

    opened by ryantxu 8
  • Move SpatialOperation from lucene to spatial4j

    Move SpatialOperation from lucene to spatial4j

    Right now the spatial operation code is in the lucene module. This means that libraries require lucene core to know the supported operations. We should have access to the operations from client code

    Lets move this to spatial4j

    opened by ryantxu 7
  • [CORE] Add normalizePoint convenience method

    [CORE] Add normalizePoint convenience method

    Instead of relying on two separate axis normalization methods, this single convenience method normalizes a Point to fall within world bounds, correctly handling antipodal longitudes when latitude values wrap the poles. Note: randomized testing included

    opened by nknize 7
  • (supposed) improvements to dateline handling

    (supposed) improvements to dateline handling

    Note that much of this code is copied from https://github.com/spatial4j/spatial4j/blob/185132fae6897f57faacdac91c0a98a92e380bfc/src/main/java/com/spatial4j/core/shape/jts/JtsGeometry.java.

    Note that I have (somewhat arbitrarily and regrettably) removed the Date-Line operations from JtsGeometry.

    A few modifications have been made:

    • Addressed a TODO -- Negative pages are handled by pageGeom() (AKA cutUnwrappedGeomInto360), which allows for the removal of redundant shifting.
    • The boundaries of the date-line have been generalized (in order to work with generic projections).
    • Rather than unioning paged geometries, they are merely "collected" into a single geometry (for efficiency's sake). This is done by a new method -- collect(). )Perhaps I've missed something here and the use of union is actually crucial in some cases)
    • Extended unwrapDateline() to handle coordinates outside of the bounds.
    • Fixed a bug inunwrapDateline that invokes Geometry.geometryChanged() for instances of GeometryCollection, which gave rise to another bug in that GeometryCollection.intersects() is an illegal operation, and so...
    • These operations have been extended to direct instances of GeometryCollection (i.e. non-subclasses)

    Otherwise, some assertions have been removed (sorry), and the style is probably not quite on.

    Let me know if you'd like to see some of these changes in with the actual code (as of now, this class is entirely independent, for the purpose of demonstration).

    opened by sttawm 7
  • WKT syntax for rectangles

    WKT syntax for rectangles

    Support should be added for the following WKT syntax. I don't think it's defined in any standard, but several existing GIS libraries/systems already support this syntax (including PostGIS and Geotoolkit).

    BOX2D(-180.0 -90.0, 180.0 90.0)

    opened by sibartlett 7
  • Some code smell reduction

    Some code smell reduction

    Hi

    I have analyzed the source code with a static analyzer and I have removed some code smell

    • Missing override
    • Removed unused parameters
    • Unused assignment
    • Boolean literals redundant
    • Unused import
    • Catches combined
    • Return redundant

    All the best matteo baccan

    opened by matteobaccan 6
  • Add support for dateline wrapping for circle to geometry conversion

    Add support for dateline wrapping for circle to geometry conversion

    Added support for dateline wrapping when converting a circle to a geometry. I implemented it like this;

    • support geometries that start at negative pages in JtsGeometry::cutUnwrappedGeomInto360()
    • put the geometry of the circle in a JtsGeometry if the circle crosses the dateline
    opened by StijnCaerts 6
  • java.lang.NoSuchMethodError: org.locationtech.jts.geom.Polygon.getExteriorRing()Lorg/locationtech/jts/geom/LineString;

    java.lang.NoSuchMethodError: org.locationtech.jts.geom.Polygon.getExteriorRing()Lorg/locationtech/jts/geom/LineString;

    When I do a SpatialPredicate.Intersects between a GeoCircle and Polygon created from the JtsShapeFactory I get an error.

    The error is a cast error on line 276 of JtsGeometry.

    SpatialRelation rel = relateEnclosedRing((LinearRing) polygon.getExteriorRing());

    I have read the comments about this being a tricky areas of the code but dont know what else I should do when I want to test a circle intersects a polygon.

    Thanks, Mike

    opened by mikes360 6
  • eclipse-jarsigner-plugin causing problems with shaded jar

    eclipse-jarsigner-plugin causing problems with shaded jar

    Hi,

    I'm using RDF4J which uses your library deeper within. When I wrap everything in a shaded jar in the end I get a signature error.

    I think it is because your jar is being signed with the eclipse jar signer plugin.

    So far I know that bouncy castle signs their jars to make sure that the crypto content isn't modified.

    Is there any such sensitive information in your jar files (eg. crypto implementations)?

    Cheers, HÃ¥vard

    opened by hmottestad 6
  • A question about distance calculations

    A question about distance calculations

    I'm quite confused about distance calculations.

    I'm using this website as a reference: https://www.omnicalculator.com/other/latitude-longitude-distance

    Then I got an implementation of a distance calculation (haversine) from here: https://tutorialspoint.dev/algorithm/geometric-algorithms/program-distance-two-points-earth

    And I want to compare this with various different implementations from Spatial4J.

    I'm using these coordinates to test with: Point 1: 40.688939, -74.04455 Point 2: 40.746853, -73.985633

    And I'm getting pretty big differences between different ways of calculating the distance between these two points.

    First, what mainly concerns me is that the website (omnicalculator) and the implementation from tutorialspoint agree completely on the distance: 8.132 km

    But none of my Spatial4J calculations agree with that number. The one that comes closest to it is the CartesianDistCalc implementation at 8.262 km. The tutorialspoint demo code claims to be using haversine but the output of Spatial4J haversine DistCalc implementation is quite a ways off at 7.313 km.

    But can somebody explain to me where these differences are coming from and what the "correct" one is?

    Below is my experimental code:

    import org.junit.jupiter.api.Test;
    import org.locationtech.spatial4j.context.SpatialContext;
    import org.locationtech.spatial4j.distance.CartesianDistCalc;
    import org.locationtech.spatial4j.distance.GeodesicSphereDistCalc;
    
    class GeoDesicCalculationTest {
        @Test
        void testGeoDesicCalculations(){
            SpatialContext ctx = SpatialContext.GEO;
    
            var startPoint = ctx.getShapeFactory().pointLatLon(40.688939, -74.04455);
            var endPoint = ctx.getShapeFactory().pointLatLon(40.746853, -73.985633);
    
            System.out.println("GEO spatial context:         " + ctx.calcDistance(startPoint, endPoint) * 100);
            System.out.println("Haversine:                   " + new GeodesicSphereDistCalc.Haversine().distance(startPoint, endPoint) * 100);
            System.out.println("Law of cosine:               " + new GeodesicSphereDistCalc.LawOfCosines().distance(startPoint, endPoint) * 100);
            System.out.println("Vincenty:                    " + new GeodesicSphereDistCalc.Vincenty().distance(startPoint, endPoint) * 100);
            System.out.println("Cartesian:                   " + new CartesianDistCalc().distance(startPoint, endPoint) * 100);
            System.out.println("Tutorials Point (haversine): " + distance(startPoint.getLat(), endPoint.getLat(), startPoint.getLon(), endPoint.getLon()));
        }
    
        public static double distance(double lat1, double lat2, double lon1, double lon2) {
            // The math module contains a function
            // named toRadians which converts from
            // degrees to radians.
            lon1 = Math.toRadians(lon1);
            lon2 = Math.toRadians(lon2);
            lat1 = Math.toRadians(lat1);
            lat2 = Math.toRadians(lat2);
    
            // Haversine formula
            double dlon = lon2 - lon1;
            double dlat = lat2 - lat1;
            double a = Math.pow(Math.sin(dlat / 2), 2)
                    + Math.cos(lat1) * Math.cos(lat2)
                    * Math.pow(Math.sin(dlon / 2),2);
    
            double c = 2 * Math.asin(Math.sqrt(a));
    
            // Radius of earth in kilometers. Use 3956
            // for miles
            double r = 6371;
    
            // calculate the result
            return(c * r);
        }
    }
    

    And the output of running it:

    GEO spatial context:         7.31307025220976
    Haversine:                   7.31307025220976
    Law of cosine:               7.313070251733588
    Vincenty:                    7.3130702522095286
    Cartesian:                   8.261503667613857
    Tutorials Point (haversine): 8.131763102409689
    

    I'm multiplying the Spatial4J calculations by 100 which is also confusing to me... it doesn't really make sense that Spatial4J is giving me answers as 1/100th of a kilometer???

    I realise I must be doing something wrong or completely misunderstanding some premises here. I would really appreciate some help in understanding what I'm doing wrong.

    opened by StFS 0
  • unwrapDateline on a polygon with a hole

    unwrapDateline on a polygon with a hole

    https://github.com/locationtech/spatial4j/blob/2926812ae302c6e0f24fb5995b1fd24be7fe0b56/src/main/java/org/locationtech/spatial4j/shape/jts/JtsGeometry.java#L492

    Why does this check in unwrapDateline() require the exterior ring of a polygon to contains() any interior rings? Doesn't contains() on two LineStrings require one to be a subset of the other? If so, you wouldn't be able to have polygons that contain holes and cross the dateline, which is the problem I'm running into.

    opened by jrnorth 0
  • JtsShapeFactory MultipolygonBuilder fails to validate shape

    JtsShapeFactory MultipolygonBuilder fails to validate shape

    It is possible to create invalid shapes through the JtsShapeFactory.MultipolygonBuilder.

    You can reproduce by running the following class:

    import org.locationtech.spatial4j.context.jts.JtsSpatialContext;
    import org.locationtech.spatial4j.context.jts.JtsSpatialContextFactory;
    import org.locationtech.spatial4j.exception.InvalidShapeException;
    import org.locationtech.spatial4j.shape.jts.JtsShapeFactory;
    
    public class Main {
    
        public static void main(String[] args) throws Exception {
            JtsSpatialContextFactory ctxFactory = new JtsSpatialContextFactory();
            ctxFactory.geo = false;
            ctxFactory.useJtsLineString = true;
            ctxFactory.useJtsMulti = true;
            ctxFactory.useJtsPoint = true;
            JtsSpatialContext ctx = new JtsSpatialContext(ctxFactory);
            JtsShapeFactory shapeFactory = new JtsShapeFactory(ctx, ctxFactory);
    
            JtsShapeFactory.PolygonBuilder polygonBuilder = shapeFactory.polygon()
                    .pointLatLon(1, 1)
                    .pointLatLon(-1, -1)
                    .pointLatLon(1, -1)
                    .pointLatLon(-1, 1)
                    .pointLatLon(1, 1);
    
            try {
                polygonBuilder.build();
                System.out.println("OK");
            } catch (InvalidShapeException e) {
                System.out.println("KO: " + e.getMessage());
            }
            try {
                shapeFactory.multiPolygon().add(polygonBuilder).build();
                System.out.println("OK");
            } catch (InvalidShapeException e) {
                System.out.println("KO: " + e.getMessage());
            }
        }
    
    }
    

    Output:

    KO: Self-intersection at or near point (0.0, 0.0, NaN)
    OK
    

    The JtsShapeFactory.MultipolygonBuilder is used in the ShapeDeserializer and GeometryDeserializer classes and can lead jackson to create invalid shapes.

    opened by PapaStan 3
  • Split packages between spatial4j and spatial4j-*-tests

    Split packages between spatial4j and spatial4j-*-tests

    These artifacts have classes in the same package which causes major headaches if one wants to use them together with the module system. Would it be at all possible to separate packages between these two modules?

    opened by dweiss 3
  • Validation of the polygon with spatial4j library fails

    Validation of the polygon with spatial4j library fails

    Hi everyone, I have a small application that I'm using to verify if geojson files are correct. also checked with https://geojsonlint.com/

    { "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [ [ [170, -9.9], [172.1, -13.2], [177, -5], [-170.1, -5.7], [170, -9], [170, -9.9] ] ] } }] }

    ` package com.company.jts_test;

    import org.locationtech.jts.geom.*; import org.locationtech.jts.util.GeometricShapeFactory; import org.locationtech.spatial4j.context.jts.JtsSpatialContext; import org.locationtech.spatial4j.shape.jts.JtsGeometry; import org.locationtech.spatial4j.shape.jts.JtsShapeFactory;

    import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List;

    public class Main {

    /** WGS 84 SRID. */
    private static final int SRID = 4326;
    /** JTS Floating Precision Model. */
    private static final PrecisionModel PRECISION_MODEL = new PrecisionModel(PrecisionModel.FLOATING);
    
    /** The Constant JTS_SPATIAL_CONTEXT. */
    private static final JtsSpatialContext JTS_SPATIAL_CONTEXT =  JtsSpatialContext.GEO;
    
    /** The Constant JTS_SHAPE_FACTORY. */
    private static final JtsShapeFactory JTS_SHAPE_FACTORY = JTS_SPATIAL_CONTEXT.getShapeFactory();
    
    /** The Constant JTS_GEOMETRY_FACTORY. */
    private static final GeometryFactory JTS_GEOMETRY_FACTORY = JTS_SHAPE_FACTORY.getGeometryFactory();
    
    /**
     * JTS Geometry Factory with floating {@link #PRECISION_MODEL} and WGS 85 {@link #SRID}.
     */
    public static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory(PRECISION_MODEL, SRID);
    
    /** The Constant GEOMETRY_SHAPE_FACTORY. */
    public static final GeometricShapeFactory GEOMETRY_SHAPE_FACTORY = new GeometricShapeFactory(GEOMETRY_FACTORY);
    
    
    public static void main(String[] args) {
    
        try {
            var d =  convert(null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    
    public static Collection<Object> convert(byte[] rawData) throws IOException {
        Collection<Object> result = new ArrayList<>();
    
            Collection<Coordinate2D> p = new ArrayList<>();
            List<List<Double>> coordinates = (List<List<Double>>) List.of(
                    List.of(170.0, -9.9),
                    List.of(172.1, -13.2),
                    List.of(177.0, -5.0),
                    List.of(-170.1, -5.7),
                    List.of(170.0, -9.0),
                    List.of(170.0, -9.9)
            );
    
    
        for (List<Double> point : coordinates) {
                p.add(new Coordinate2D(point.get(1), point.get(0)));
            }
    
            isPolygonValid(p);
    
        return result;
    }
    
    private static JtsWxError isPolygonValid(Collection<Coordinate2D> p) {
        Coordinate[] c = p.stream().map(coordinate -> new Coordinate(coordinate.getLongitude(), coordinate.getLatitude())).toArray(Coordinate[]::new);
        return isPolygonValid(c);
    }
    
    public static JtsWxError isPolygonValid(Coordinate[] coordinates) {
        Polygon geometry = JTS_GEOMETRY_FACTORY.createPolygon(coordinates);
        return validateGeometry(geometry);
    }
    
    private static JtsWxError validateGeometry(Polygon geometry) {
        if(geometry == null) {
            return new JtsWxError(1,"");
        }
       // try {
            JtsGeometry jtsGeometry = (JtsGeometry) JTS_SHAPE_FACTORY.makeShapeFromGeometry(geometry);
            jtsGeometry.validate();
       // }
        //catch(Exception exception) {
        //    return new JtsWxError(1,exception.getMessage());
       // }
        return new JtsWxError(1,"OK");
    }
    

    } `

    Exception in thread "main" org.locationtech.jts.geom.TopologyException: found non-noded intersection between LINESTRING ( 172.1 -13.2, 177 -5 ) and LINESTRING ( 180 -7.341708542713568, 170 -9 ) [ (175.11679477586557, -8.151486293449425, NaN) ] at org.locationtech.jts.noding.FastNodingValidator.checkValid(FastNodingValidator.java:139) at org.locationtech.jts.geomgraph.EdgeNodingValidator.checkValid(EdgeNodingValidator.java:80) at org.locationtech.jts.geomgraph.EdgeNodingValidator.checkValid(EdgeNodingValidator.java:45) at org.locationtech.jts.operation.overlay.OverlayOp.computeOverlay(OverlayOp.java:229) at org.locationtech.jts.operation.overlay.OverlayOp.getResultGeometry(OverlayOp.java:181) at org.locationtech.jts.operation.overlay.OverlayOp.overlayOp(OverlayOp.java:84) at org.locationtech.jts.operation.overlay.snap.SnapIfNeededOverlayOp.getResultGeometry(SnapIfNeededOverlayOp.java:75) at org.locationtech.jts.operation.overlay.snap.SnapIfNeededOverlayOp.overlayOp(SnapIfNeededOverlayOp.java:37) at org.locationtech.jts.geom.GeometryOverlay.overlay(GeometryOverlay.java:76) at org.locationtech.jts.geom.GeometryOverlay.intersection(GeometryOverlay.java:119) at org.locationtech.jts.geom.Geometry.intersection(Geometry.java:1330) at org.locationtech.spatial4j.shape.jts.JtsGeometry.cutUnwrappedGeomInto360(JtsGeometry.java:585) at org.locationtech.spatial4j.shape.jts.JtsGeometry.<init>(JtsGeometry.java:67) at org.locationtech.spatial4j.shape.jts.JtsShapeFactory.makeShape(JtsShapeFactory.java:531) at org.locationtech.spatial4j.shape.jts.JtsShapeFactory.makeShape(JtsShapeFactory.java:548) at org.locationtech.spatial4j.shape.jts.JtsShapeFactory.makeShapeFromGeometry(JtsShapeFactory.java:500) at com.company.jts_test.Main.validateGeometry(Main.java:88) at com.company.jts_test.Main.isPolygonValid(Main.java:80) at com.company.jts_test.Main.isPolygonValid(Main.java:75) at com.company.jts_test.Main.convert(Main.java:68) at com.company.jts_test.Main.main(Main.java:43)

    opened by moniuh 1
  • Support JTS 18.1

    Support JTS 18.1

    Hello,

    We are using Lucene and Geotools in our application and tried to update to a newer Geotools version. Now our tests in lucene fail, because of spatial4j dependency. Geotools is now using JTS 18.1 and there is an incompatibility compared to JTS 17.0 in spatial4j. The InStream in org.locationtech.spatial4j.io.jts.JtsBinaryCodec.readJtsGeom(DataInput) has now a return type int instead of void.

    This should be an easy fix, I will try to provide a PullRequest for that.

    opened by GisMarsch 0
Releases(spatial4j-0.8)
  • spatial4j-0.8(Nov 27, 2020)

    This is a minor release update to Spatial4j. Spatial4j is in a maintenance mode, receiving infrequent minor changes. This release has no changes to dependencies except that some versions were updated. The minimum Java version is now 1.8.

    from CHANGES.md

    #197: Require Java 8, AKA v1.8. (David Smiley)

    #194: Circles that cross a dateline can now be converted to a JTS Geometry. Previous attempts would throw an exception. (Stijn Caerts)

    #194: JtsGeometry now supports input an Geometry that crosses the dateline multiple times (wraps the globe multiple times). Previous attempts would yield erroneous behavior. (Stijn Caerts)

    #188: Upgraded to JTS 1.17.0. This JTS release has a small API change. (Jim Hughes)

    #177: Improve conversion of a Circle to Shape. JtsShapeFactory allows converting from a Shape object to a JTS Geometry object. Geodetic circles now translate to a polygon that has points equidistant from the center. Before the change, there was potentially a large inaccuracy. (Hrishi Bakshi)

    #163: "Empty" points in JTS are now convertible to a Spatial4j Shape instead of throwing an exception. (David Smiley)

    #162: Fixed WKT & GeoJSON [de]serialization of "empty" points and geometrycollections. (Jeen Broekstra, David Smiley)

    #165: Added ShapeFactory.pointLatLon convenience method. (MoeweX)

    #167: WKTWriter now has a means to customize the NumberFromat. (MoeweX)

    #175: ShapesAsWKTModule, a Jackson databind module, didn't deserialize WKT inside JSON to a Spatial4j Shape at all. Now it does. It continues to serialize correctly. (David Smiley)

    Source code(tar.gz)
    Source code(zip)
    spatial4j-0.8-javadoc.jar(609.77 KB)
    spatial4j-0.8-sources.jar(135.48 KB)
    spatial4j-0.8-tests.jar(146.83 KB)
    spatial4j-0.8.jar(185.83 KB)
    spatial4j-0.8.pom(15.82 KB)
GeoServer is an open source software server written in Java that allows users to share and edit geospatial data

GeoServer is an open source software server written in Java that allows users to share and edit geospatial data. Designed for interoperability, it publishes data from any major spatial data source using open standards.

GeoServer 3k Jan 1, 2023
Open source routing engine for OpenStreetMap. Use it as Java library or server.

GraphHopper Routing Engine GraphHopper is a fast and memory efficient Java routing engine, released under Apache License 2.0. By default it uses OpenS

GraphHopper 4k Jan 3, 2023
The JTS Topology Suite is a Java library for creating and manipulating vector geometry.

JTS Topology Suite The JTS Topology Suite is a Java library for creating and manipulating vector geometry. It also provides a comprehensive set of geo

LocationTech 1.5k Jan 6, 2023
Vector map library and writer - running on Android and Desktop.

Mapsforge See the integration guide and changelog. And read through how to contribute guidelines. If you have any questions or problems, don't hesitat

mapsforge 1k Dec 30, 2022
An easy-to-implement library for the GeoHash algorithm

Overview An easy-to-implement library that can assist Java developers in using the GeoHash algorithm in order to create geocodes based on custom latit

Asterios Raptis 63 Mar 25, 2022
Vector map library and writer - running on Android and Desktop.

Mapsforge See the integration guide and changelog. And read through how to contribute guidelines. If you have any questions or problems, don't hesitat

mapsforge 1k Jan 7, 2023
Geohash utitlies in java

geo Java utility methods for geohashing. Status: production, available on Maven Central Maven site reports are here including javadoc. Add this to you

Dave Moten 385 Dec 27, 2022
Geohash utitlies in java

geo Java utility methods for geohashing. Status: production, available on Maven Central Maven site reports are here including javadoc. Add this to you

Dave Moten 386 Jan 1, 2023
Java/JNI bindings to libpostal for for fast international street address parsing/normalization

jpostal These are the Java/JNI bindings to libpostal, a fast, multilingual NLP library (written in C) for parsing/normalizing physical addresses aroun

openvenues 94 Oct 15, 2022
LocationTech Spatial4j: A Geospatial Library for Java

Spatial4j (note: Spatial4j's official home page is at LocationTech: https://projects.eclipse.org/projects/locationtech.spatial4j but this README has r

LocationTech 880 Dec 23, 2022
GeoServer is an open source software server written in Java that allows users to share and edit geospatial data

GeoServer is an open source software server written in Java that allows users to share and edit geospatial data. Designed for interoperability, it publishes data from any major spatial data source using open standards.

GeoServer 3k Jan 1, 2023
Duck Library is a library for developers who don't want to spend their time to write same library consistently.

Duck Library is a library for developers who don't want to spend their time to write same library consistently. It has almost every useful feature to

null 5 Jul 28, 2022
This is an automated library software built in Java Netbeans to reduce manual efforts of the librarian, students to ensure smooth functioning of library by involving RFIDs.

Advanced-Library-Automation-System This is an advanced automated library software built in Java Netbeans to reduce manual efforts of the librarian, st

DEV_FINWIZ 14 Dec 6, 2022
Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstall apk.

Tinker Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstalling apk. Getting started Add t

Tencent 16.6k Dec 30, 2022
Diff Utils library is an OpenSource library for performing the comparison / diff operations between texts or some kind of data: computing diffs

Diff Utils library is an OpenSource library for performing the comparison / diff operations between texts or some kind of data: computing diffs, applying patches, generating unified diffs or parsing them, generating diff output for easy future displaying (like side-by-side view) and so on.

null 951 Jan 5, 2023
Microserver is a Java 8 native, zero configuration, standards based, battle hardened library to run Java Rest Microservices via a standard Java main class. Supporting pure Microservice or Micro-monolith styles.

Microserver A convenient modular engine for Microservices. Microserver plugins offer seamless integration with Spring (core), Jersey, Guava, Tomcat, G

AOL 936 Dec 19, 2022
Microserver is a Java 8 native, zero configuration, standards based, battle hardened library to run Java Rest Microservices via a standard Java main class. Supporting pure Microservice or Micro-monolith styles.

Microserver is a Java 8 native, zero configuration, standards based, battle hardened library to run Java Rest Microservices via a standard Java main class. Supporting pure Microservice or Micro-monolith styles.

AOL 936 Dec 19, 2022
Inria 1.4k Dec 29, 2022
A Java serialization/deserialization library to convert Java Objects into JSON and back

Gson Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to a

Google 21.7k Jan 8, 2023