← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 12846: 'Get org units inside radius' implementation.

 

------------------------------------------------------------
revno: 12846
committer: James Chang <jamesbchang@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2013-11-01 15:11:31 +0700
message:
  'Get org units inside radius' implementation.
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/hibernate/HibernateOrganisationUnitStore.java
  dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/MapUtils.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ValidationUtils.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/organisationunit/OrganisationUnitController.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitService.java	2013-08-23 15:56:19 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitService.java	2013-11-01 08:11:31 +0000
@@ -381,6 +381,19 @@
 
     Collection<OrganisationUnit> getOrganisationUnitsBetweenByStatusLastUpdated( boolean status, Date lastUpdated, int first, int max );
 
+    /**
+     * Retrieves the objects where its coordinate is within the 4 area points.
+     * 4 area points are
+     * Index 0: Maximum latitude (north edge of box shape)
+     * Index 1: Maxium longitude (east edge of box shape)
+     * Index 2: Minimum latitude (south edge of box shape)
+     * Index 3: Minumum longitude (west edge of box shape)
+     *
+     * @param box      the 4 area points.
+     * @return collection of objects.
+     */
+    Collection<OrganisationUnit> getWithinCoordinateArea( double[] box );
+    
     // -------------------------------------------------------------------------
     // OrganisationUnitHierarchy
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitStore.java	2013-08-23 15:56:19 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/organisationunit/OrganisationUnitStore.java	2013-11-01 08:11:31 +0000
@@ -161,6 +161,20 @@
      */
     Collection<OrganisationUnit> getBetweenByStatusLastUpdated( boolean status, Date lastUpdated, int first, int max );
 
+
+    /**
+     * Retrieves the objects where its coordinate is within the 4 area points.
+     * 4 area points are
+     * Index 0: Maximum latitude (north edge of box shape)
+     * Index 1: Maxium longitude (east edge of box shape)
+     * Index 2: Minimum latitude (south edge of box shape)
+     * Index 3: Minumum longitude (west edge of box shape)
+     *
+     * @param box      the 4 area points.
+     * @return collection of objects.
+     */
+    Collection<OrganisationUnit> getWithinCoordinateArea( double[] box );
+    
     // -------------------------------------------------------------------------
     // OrganisationUnitHierarchy
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java	2013-08-23 16:05:01 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/DefaultOrganisationUnitService.java	2013-11-01 08:11:31 +0000
@@ -798,6 +798,11 @@
         return organisationUnitLevelStore.getMaxLevels();
     }
 
+    public Collection<OrganisationUnit> getWithinCoordinateArea( double[] box )
+    {
+        return organisationUnitStore.getWithinCoordinateArea( box );
+    }
+    
     // -------------------------------------------------------------------------
     // Version
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/hibernate/HibernateOrganisationUnitStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/hibernate/HibernateOrganisationUnitStore.java	2013-08-23 16:05:01 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/organisationunit/hibernate/HibernateOrganisationUnitStore.java	2013-11-01 08:11:31 +0000
@@ -267,6 +267,20 @@
         return criteria.list();
     }
 
+    @SuppressWarnings("unchecked")
+    public Collection<OrganisationUnit> getWithinCoordinateArea( double[] box )
+    {
+        return getQuery( "from OrganisationUnit o"
+            + " where o.featureType='Point'"
+            + " and o.coordinates is not null"
+            + " and CAST( SUBSTRING(o.coordinates, 2, LOCATE(',', o.coordinates) - 2) AS big_decimal ) >= " + box[3]
+            + " and CAST( SUBSTRING(o.coordinates, 2, LOCATE(',', o.coordinates) - 2) AS big_decimal ) <= " + box[1] 
+            + " and CAST( SUBSTRING(coordinates, LOCATE(',', o.coordinates) + 1, LOCATE(']', o.coordinates) - LOCATE(',', o.coordinates) - 1 ) AS big_decimal ) >= " + box[2] 
+            + " and CAST( SUBSTRING(coordinates, LOCATE(',', o.coordinates) + 1, LOCATE(']', o.coordinates) - LOCATE(',', o.coordinates) - 1 ) AS big_decimal ) <= " + box[0] 
+            ).list();
+    }
+    
+        
     // -------------------------------------------------------------------------
     // OrganisationUnitHierarchy
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/MapUtils.java'
--- dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/MapUtils.java	2013-10-28 13:17:58 +0000
+++ dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/MapUtils.java	2013-11-01 08:11:31 +0000
@@ -30,6 +30,7 @@
 
 import java.awt.Color;
 import java.awt.Graphics2D;
+import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.RenderingHints;
 import java.awt.geom.Point2D;
@@ -337,4 +338,17 @@
         
         return box;
     }
+    
+    /**
+     * Creates the distance between two points.
+     */
+    public static double getDistanceBetweenTwoPoints( Point2D from, Point2D to)
+    {                        
+        GeodeticCalculator calc = new GeodeticCalculator();
+        calc.setStartingGeographicPoint( from );
+        calc.setDestinationGeographicPoint( to);
+        
+        return calc.getOrthodromicDistance();
+    }
+    
 }

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ValidationUtils.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ValidationUtils.java	2013-10-07 17:58:57 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/ValidationUtils.java	2013-11-01 08:11:31 +0000
@@ -33,6 +33,7 @@
 import org.apache.commons.validator.routines.UrlValidator;
 import org.hisp.dhis.dataelement.DataElement;
 
+import java.awt.geom.Point2D;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
@@ -198,6 +199,29 @@
         return matcher.find() ? matcher.group( 2 ) : null;
     }
 
+
+    /**
+     * Returns the longitude and latitude from the given coordinate.
+     *
+     * @param coordinate the coordinate string.
+     * @return Point2D of the coordinate.
+     */
+    public static Point2D getCoordinatePoint2D( String coordinate )
+    {
+        if ( coordinate == null )
+        {
+            return null;
+        }
+
+        Matcher matcher = POINT_PATTERN.matcher( coordinate );
+
+        if( matcher.find() && matcher.groupCount() == 2 )
+        {
+            return new Point2D.Double( Double.parseDouble( matcher.group( 1 ) ), Double.parseDouble( matcher.group( 2 ) ) );
+        }
+        else return null;        
+    }
+
     /**
      * Returns a coordinate string based on the given latitude and longitude.
      * The coordinate is on the form longitude / latitude.

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/organisationunit/OrganisationUnitController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/organisationunit/OrganisationUnitController.java	2013-10-30 10:44:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/organisationunit/OrganisationUnitController.java	2013-11-01 08:11:31 +0000
@@ -33,11 +33,17 @@
 import org.hisp.dhis.api.controller.WebOptions;
 import org.hisp.dhis.api.controller.exception.NotFoundException;
 import org.hisp.dhis.api.utils.WebUtils;
+import org.hisp.dhis.attribute.Attribute;
+import org.hisp.dhis.attribute.AttributeValue;
 import org.hisp.dhis.common.Pager;
 import org.hisp.dhis.dxf2.metadata.MetaData;
+import org.hisp.dhis.dxf2.utils.JacksonUtils;
+import org.hisp.dhis.mapgeneration.MapUtils;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroup;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.organisationunit.comparator.OrganisationUnitByLevelComparator;
+import org.hisp.dhis.system.util.ValidationUtils;
 import org.hisp.dhis.user.CurrentUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
@@ -50,11 +56,15 @@
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
+import java.awt.geom.Point2D;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -247,4 +257,67 @@
 
         return StringUtils.uncapitalize( getEntitySimpleName() );
     }
+    
+    
+    @RequestMapping(value = "/withinRange", method = RequestMethod.GET, produces = { "*/*", "application/json" })
+    public void getEntitiesWithinRange( @RequestParam Map<String, String> parameters,
+        Model model, HttpServletRequest request, HttpServletResponse response ) throws Exception
+    {
+        List<OrganisationUnit> entityList;
+
+        WebOptions options = new WebOptions( parameters );
+
+        Double longitude = Double.parseDouble( options.getOptions().get( "longitude" ) );
+        Double latitude = Double.parseDouble( options.getOptions().get( "latitude" ) );
+        Double distance = Double.parseDouble( options.getOptions().get( "distance" ) );
+        
+        entityList = new ArrayList<OrganisationUnit>( organisationUnitService.getWithinCoordinateArea( MapUtils.getBoxShape( longitude, latitude, distance ) ) );
+        
+        Point2D centerPoint = new Point2D.Double( longitude, latitude );
+        
+        if ( entityList != null )
+        {
+            Iterator<OrganisationUnit> iter = entityList.iterator();
+
+            while ( iter.hasNext() )
+            {
+                OrganisationUnit orgunit = iter.next();
+
+                double distancebetween = MapUtils.getDistanceBetweenTwoPoints( centerPoint,
+                    ValidationUtils.getCoordinatePoint2D( orgunit.getCoordinates() ) );
+
+                if ( distancebetween > distance )
+                {
+                    // Remove the orgUnits that is outside of the distance range 
+                    // - due to the 'getWithinCoordinateArea' looking at square area instead of circle.
+                    iter.remove();
+                }
+                else
+                {
+                    // Clear out all data not needed for this task
+                    orgunit.removeAllDataSets();
+                    orgunit.removeAllUsers();
+                    orgunit.removeAllOrganisationUnitGroups();
+
+                    Set<AttributeValue> attributeValues = orgunit.getAttributeValues();
+                    attributeValues.clear();
+
+                    // Add OrgUnit Group Symbol into attributes
+                    for ( OrganisationUnitGroup orgunitGroup : orgunit.getGroups() )
+                    {
+                        AttributeValue attributeValue = new AttributeValue();
+                        attributeValue.setAttribute( new Attribute( "OrgUnitGroupSymbol", "OrgUnitGroupSymbol" ) );
+                        attributeValue.setValue( orgunitGroup.getSymbol() );
+
+                        attributeValues.add( attributeValue );
+                    }
+
+                    orgunit.setAttributeValues( attributeValues );
+                }
+            }
+        }
+
+        JacksonUtils.toJson( response.getOutputStream(), entityList );
+    }    
+    
 }