javapostgresqlgradlepostgishibernate-spatial

Long and Lat values not passing to .createPoint(new Coordinate(long, lat));


I am using Hibernate Spatial, Postgres/Postgis, Spring Boot Gradle.

I am currently trying to populate point data to my Postgres/Postgis database. I am able to create a point -- however, when I pass my variables double longitude and double latitude, my Point writes to the database as (0,0).

I know my variables double longitude and double latitude have values, because they write to the database, in their own columns, the values the user inputs.

When I manually type in the coordinates, e.g.

.createPoint(new Coordinate (-120, 20))

my point data populates correctly.

Why are the actual numerical doubles passing, but not the values of my variables?

Thanks in advance!!

Here is my code:


import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.PrecisionModel;
import javax.persistence.Entity;
import javax.validation.constraints.NotNull;

@Entity
public class Gem extends AbstractEntity {
  
    @NotNull
    double longitude;

    @NotNull
    double latitude

    public Gem() {}

    public double getLongitude() {
        return longitude;
    }
    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public double getLatitude() {
        return latitude;
    }
    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public Point getGemPoint() {
        return gemPoint;
    }

    public void setGemPoint(Point gemPoint) {
        this.gemPoint = gemPoint;

    }

    GeometryFactory geomFactory = new GeometryFactory(new PrecisionModel(), 4326);
    Point gemPoint = geomFactory.createPoint(new Coordinate(longitude, latitude));
}


 

Solution

  • The type double default value is 0.0d according to this documentation: Java: Primitive Data Types

    If you create an instance like this:

    Gem gem = new Gem();
    

    the latitude and longitude will be zero and and after that createPoint function:

    GeometryFactory geomFactory = new GeometryFactory(new PrecisionModel(), 4326);
    Point gemPoint = geomFactory.createPoint(new Coordinate(longitude, latitude));
    

    Use these previously default zero values.

    One possible solution is the following:

    @Entity
    public class Gem extends AbstractEntity {
      
        @NotNull
        double longitude;
    
        @NotNull
        double latitude
        
        Point gemPoint;           //<- gemPoint moved here
    
        public Gem() {}
    
        public double getLongitude() {
            return longitude;
        }
        public void setLongitude(double longitude) {
            this.longitude = longitude;
            recalculate();       // <- call recalculate after set
        }
    
        public void setLatitude(double latitude) {
            this.latitude = latitude;
            recalculate();       // <- call recalculate after set
        }
    
        public void setGemPoint(Point gemPoint) {
            this.gemPoint = gemPoint;
            this.latitude = gemPoint.getY(); // <- when gemPoint set via setter ensure the consistency of latitude and longitude if required
            this.longitude = gemPoint.getX();
        }    
        
        // create the recalculate method to update gemPoint accoring to current latitude and longitude values
        private void recalculate() {
            GeometryFactory geomFactory = new GeometryFactory(new PrecisionModel(), 4326);
            gemPoint = geomFactory.createPoint(new Coordinate(longitude, latitude));
        }
    

    After that if you run:

            Gem gem = new Gem();
            gem.setLatitude(40);
            gem.setLongitude(70);
    

    The inner gemPoint will be contain the (70 40) values.