From aa19e881517c65bd05cadbbed96e57682e481b9b Mon Sep 17 00:00:00 2001 From: bertrand <bpinel@ippon.fr> Date: Fri, 15 Sep 2017 11:35:58 +0200 Subject: [PATCH] Add Web service to retrieve cities inside a given perimeter --- .../fr/ippon/geohipster/domain/Geocity.java | 21 ++++++++++++++++ .../repository/GeocityRepository.java | 7 +++++- .../geohipster/service/GeocityService.java | 12 ++++++++++ .../service/impl/GeocityServiceImpl.java | 15 ++++++++++++ .../geohipster/web/rest/GeocityResource.java | 24 +++++++++++++++++++ .../20170914101249_added_entity_Geocity.xml | 5 ++++ 6 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/main/java/fr/ippon/geohipster/domain/Geocity.java b/src/main/java/fr/ippon/geohipster/domain/Geocity.java index 8c2907e..7c728b9 100644 --- a/src/main/java/fr/ippon/geohipster/domain/Geocity.java +++ b/src/main/java/fr/ippon/geohipster/domain/Geocity.java @@ -36,6 +36,11 @@ public class Geocity implements Serializable { @Column(name = "location") private Point location; + @Expose + private double lat; + @Expose + private double lon; + @Column(name = "featureclass") private String featureclass; @@ -269,6 +274,22 @@ public class Geocity implements Serializable { this.location = location; } + public double getLat() { + return lat; + } + + public void setLat(double lat) { + this.lat = lat; + } + + public double getLon() { + return lon; + } + + public void setLon(double lon) { + this.lon = lon; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/src/main/java/fr/ippon/geohipster/repository/GeocityRepository.java b/src/main/java/fr/ippon/geohipster/repository/GeocityRepository.java index b690549..a471f45 100644 --- a/src/main/java/fr/ippon/geohipster/repository/GeocityRepository.java +++ b/src/main/java/fr/ippon/geohipster/repository/GeocityRepository.java @@ -1,10 +1,14 @@ package fr.ippon.geohipster.repository; import fr.ippon.geohipster.domain.Geocity; +import org.geolatte.geom.Geometry; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import org.springframework.data.jpa.repository.*; +import java.util.List; + /** * Spring Data JPA repository for the Geocity entity. @@ -12,5 +16,6 @@ import org.springframework.data.jpa.repository.*; @SuppressWarnings("unused") @Repository public interface GeocityRepository extends JpaRepository<Geocity,Long> { - + @Query("SELECT c FROM Geocity c WHERE dwithin(c.location, :point, :dist)=true") + public List<Geocity> findCityWithinCircle(@Param("point")Geometry point, @Param("dist")float dist); } diff --git a/src/main/java/fr/ippon/geohipster/service/GeocityService.java b/src/main/java/fr/ippon/geohipster/service/GeocityService.java index ba5c696..2a0d974 100644 --- a/src/main/java/fr/ippon/geohipster/service/GeocityService.java +++ b/src/main/java/fr/ippon/geohipster/service/GeocityService.java @@ -4,6 +4,8 @@ import fr.ippon.geohipster.domain.Geocity; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import java.util.List; + /** * Service Interface for managing Geocity. */ @@ -39,4 +41,14 @@ public interface GeocityService { * @param id the id of the entity */ void delete(Long id); + + /** + * + * @param lat : latitude for center point + * @param lon : longitude for center point + * @param radius : radius in meters for the search + * @return + */ + List<Geocity> findCitiesWithinCircle(float lat, float lon, int radius); + } diff --git a/src/main/java/fr/ippon/geohipster/service/impl/GeocityServiceImpl.java b/src/main/java/fr/ippon/geohipster/service/impl/GeocityServiceImpl.java index c0ae096..df53dde 100644 --- a/src/main/java/fr/ippon/geohipster/service/impl/GeocityServiceImpl.java +++ b/src/main/java/fr/ippon/geohipster/service/impl/GeocityServiceImpl.java @@ -3,6 +3,10 @@ package fr.ippon.geohipster.service.impl; import fr.ippon.geohipster.service.GeocityService; import fr.ippon.geohipster.domain.Geocity; import fr.ippon.geohipster.repository.GeocityRepository; +import org.geolatte.geom.G2D; +import org.geolatte.geom.Point; +import org.geolatte.geom.Position; +import org.geolatte.geom.crs.CrsRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; @@ -10,6 +14,8 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + /** * Service Implementation for managing Geocity. @@ -74,4 +80,13 @@ public class GeocityServiceImpl implements GeocityService{ log.debug("Request to delete Geocity : {}", id); geocityRepository.delete(id); } + + @Override + public List<Geocity> findCitiesWithinCircle(float lat, float lon, int radius) { + Position g2d = new G2D(lon, lat); + Point point = new Point(g2d, CrsRegistry.getCoordinateReferenceSystemForEPSG(4326, null)); + float geoRadius = radius/110.0f; + + List<Geocity> cities = geocityRepository.findCityWithinCircle(point, geoRadius); + return cities; } } diff --git a/src/main/java/fr/ippon/geohipster/web/rest/GeocityResource.java b/src/main/java/fr/ippon/geohipster/web/rest/GeocityResource.java index 94af5aa..da553a5 100644 --- a/src/main/java/fr/ippon/geohipster/web/rest/GeocityResource.java +++ b/src/main/java/fr/ippon/geohipster/web/rest/GeocityResource.java @@ -1,6 +1,8 @@ package fr.ippon.geohipster.web.rest; import com.codahale.metrics.annotation.Timed; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import fr.ippon.geohipster.domain.Geocity; import fr.ippon.geohipster.service.GeocityService; import fr.ippon.geohipster.web.rest.util.HeaderUtil; @@ -15,6 +17,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.query.Param; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -30,6 +33,8 @@ import java.net.URISyntaxException; import java.util.List; import java.util.Optional; +import static org.springframework.web.bind.annotation.RequestMethod.GET; + /** * REST controller for managing Geocity. */ @@ -134,6 +139,22 @@ public class GeocityResource { return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build(); } + /** + * + * @param lat : Latitude for the center of the circle + * @param lon : longitude for the center of the circle + * @param radius : radius of the circle in kilometers + * @return + */ + @RequestMapping(value = "/geocities", method = GET, params = { "lat", "lon", "radius"}) + @Timed + public String getGeocitiesWithinCircle(@Param("lat") float lat, @Param("lon")float lon, @Param("radius") int radius) { + Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); // new Gson(); + List<Geocity> cities = geocityService.findCitiesWithinCircle(lat, lon, radius); + + return gson.toJson(cities); + } + @GetMapping("/loadGeoNamesCities") public void loadGeoNamesCities(){ log.info("Loading GeoName file "+FRGeonamesCityFile); @@ -154,6 +175,9 @@ public class GeocityResource { Position g2d = new G2D(new Double(columns[5]), new Double(columns[4])); Point point = new Point(g2d, CrsRegistry.getCoordinateReferenceSystemForEPSG(4326, null)); geocity.setLocation(point); + // Also copy lat / lon to duplicate columns in the Database + geocity.setLat(new Double(columns[4])); + geocity.setLon(new Double(columns[5])); geocity.setFeatureclass(columns[6]); geocity.setFeaturetype(columns[7]); diff --git a/src/main/resources/config/liquibase/changelog/20170914101249_added_entity_Geocity.xml b/src/main/resources/config/liquibase/changelog/20170914101249_added_entity_Geocity.xml index 507638c..be6f987 100644 --- a/src/main/resources/config/liquibase/changelog/20170914101249_added_entity_Geocity.xml +++ b/src/main/resources/config/liquibase/changelog/20170914101249_added_entity_Geocity.xml @@ -30,7 +30,12 @@ <column name="alternatenames" type="varchar(1000)"> <constraints nullable="true" /> </column> + <column name="location" type="geometry(Point, 4326)"/> + <!-- We keep lat / lng column for better visibility of data --> + <column name="lat" type="float4"/> + <column name="lon" type="float4"/> + <column name="featureclass" type="varchar(255)"> <constraints nullable="true" /> </column> -- GitLab