← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 12451: PNG maps, implemented support for bounday layers. Facility layers rendering as boundary layers fo...

 

------------------------------------------------------------
revno: 12451
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2013-10-07 00:11:27 +0200
message:
  PNG maps, implemented support for bounday layers. Facility layers rendering as boundary layers for now.
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/mapping/MapView.java
  dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/GeoToolsMapGenerationService.java
  dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/InternalMapLayer.java
  dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/InternalMapObject.java
  dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/Legend.java
  dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/LegendSet.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/mapping/MapView.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/mapping/MapView.java	2013-10-06 19:54:35 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/mapping/MapView.java	2013-10-06 22:11:27 +0000
@@ -166,9 +166,10 @@
         return colorLow != null && !colorLow.trim().isEmpty() && colorHigh != null && !colorHigh.trim().isEmpty();
     }
     
-    // -------------------------------------------------------------------------
-    // Getters and setters
-    // -------------------------------------------------------------------------
+    public boolean isDataLayer()
+    {
+        return DATA_LAYERS.contains( layer );
+    }
 
     @Override
     public boolean haveUniqueNames()
@@ -182,6 +183,10 @@
         return ( indicators != null && !indicators.isEmpty() ) ? indicators.get( 0 ).getName() : 
             ( dataElements != null && !dataElements.isEmpty() ) ? dataElements.get( 0 ).getName() : uid;
     }
+    
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
 
     @JsonProperty
     @JsonView( { DetailedView.class, ExportView.class, DimensionalView.class } )

=== modified file 'dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/GeoToolsMapGenerationService.java'
--- dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/GeoToolsMapGenerationService.java	2013-10-06 20:38:51 +0000
+++ dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/GeoToolsMapGenerationService.java	2013-10-06 22:11:27 +0000
@@ -47,6 +47,8 @@
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.system.filter.OrganisationUnitWithCoordinatesFilter;
+import org.hisp.dhis.system.util.FilterUtils;
 import org.springframework.util.Assert;
 
 /**
@@ -126,17 +128,24 @@
             return null;
         }
         
+        boolean dataLayer = map.getMapViews().get( 0 ).isDataLayer();
+        
         // Build representation of a map using GeoTools, then render as image
         BufferedImage mapImage = MapUtils.render( internalMap, width, height );
 
-        // Build the legend set, then render it to an image
-        LegendSet legendSet = new LegendSet( internalMap.getLayers().get( 0 ) ); //TODO
-        BufferedImage legendImage = legendSet.render();
-
-        // Combine the legend image and the map image into one image
-        BufferedImage finalImage = combineLegendAndMapImages( legendImage, mapImage );
-
-        return finalImage;
+        if ( !dataLayer )
+        {
+            return mapImage;
+        }
+        else
+        {
+            // Build the legend set, then render it to an image
+            LegendSet legendSet = new LegendSet( internalMap.getLayers().get( 0 ) ); //TODO
+            BufferedImage legendImage = legendSet.render();
+    
+            // Combine the legend image and the map image into one image
+            return combineLegendAndMapImages( legendImage, mapImage );
+        }
     }
 
     // -------------------------------------------------------------------------
@@ -150,8 +159,8 @@
     private static final String DEFAULT_STROKE_COLOR = "#ffffff";
 
     private static final int DEFAULT_STROKE_WIDTH = 1;
-    private static final int DEFAULT_RADIUS_HIGH = 35;
-    private static final int DEFAULT_RADIUS_LOW = 15;
+    private static final Integer DEFAULT_RADIUS_HIGH = 35;
+    private static final Integer DEFAULT_RADIUS_LOW = 15;
 
     private InternalMapLayer getSingleInternalMapLayer( MapView mapView )
     {
@@ -186,26 +195,15 @@
             uidOuMap.put( ou.getUid(), ou );
         }
         
-        DataQueryParams params = analyticsService.getFromAnalyticalObject( mapView, null );
-        
-        Grid grid = analyticsService.getAggregatedDataValues( params );
-
-        Collection<MapValue> mapValues = getMapValues( grid );
-
-        if ( mapValues.isEmpty() )
-        {
-            return null;
-        }
-        
         // Get the name from the external layer
         String name = mapView.getName();
 
         // Get the period
-        Period period = mapView.getPeriods().get( 0 ); //TODO make more robust
+        Period period = !mapView.getPeriods().isEmpty() ? mapView.getPeriods().get( 0 ) : null;
 
         // Get the low and high radii
-        int radiusLow = !isIndicator ? mapView.getRadiusLow() : DEFAULT_RADIUS_LOW;
-        int radiusHigh = !isIndicator ? mapView.getRadiusHigh() : DEFAULT_RADIUS_HIGH;
+        Integer radiusLow = !isIndicator ? mapView.getRadiusLow() : DEFAULT_RADIUS_LOW;
+        Integer radiusHigh = !isIndicator ? mapView.getRadiusHigh() : DEFAULT_RADIUS_HIGH;
 
         // Get the low and high colors, typically in hexadecimal form, e.g. #ff3200
         Color colorLow = MapUtils.createColorFromString( StringUtils.trimToNull( mapView.getColorLow() ) != null ? mapView.getColorLow()
@@ -237,45 +235,79 @@
         mapLayer.setStrokeColor( strokeColor );
         mapLayer.setStrokeWidth( strokeWidth );
 
-        // Build and set the internal GeoTools map objects for the layer
-        
-        for ( MapValue mapValue : mapValues )
-        {
-            // Get the org unit for this map value
-            OrganisationUnit orgUnit = uidOuMap.get( mapValue.getOu() );
-            
-            if ( orgUnit != null && orgUnit.hasCoordinates() && orgUnit.hasFeatureType() )
-            {
-                mapLayer.addSingleGeoToolsMapObject( mapValue.getValue(), orgUnit );
-            }
-        }
-
-        // Create an interval set for this map layer that distributes its map
-        // objects into their respective intervals
-        
-        if ( hasLegendSet )
-        {
-            mapLayer.setIntervalSetFromLegendSet( mapView.getLegendSet() );
-            mapLayer.distributeAndUpdateMapObjectsInIntervalSet();
-        }
-        else
-        {
-            mapLayer.applyIntervalSetToMapLayer( DistributionStrategy.STRATEGY_EQUAL_RANGE, mapLayer.getClasses() );
-            mapLayer.distributeAndUpdateMapObjectsInIntervalSet();
-        }
-        
-        // Update the radius of each map object in this map layer according to
-        // its map object's highest and lowest values
-        
-        if ( !isIndicator )
-        {
-            mapLayer.applyInterpolatedRadii();
+        if ( !mapView.isDataLayer() ) // Boundary (and facility) layer
+        {
+            List<OrganisationUnit> units = mapView.getAllOrganisationUnits();
+            
+            FilterUtils.filter( units, new OrganisationUnitWithCoordinatesFilter() );
+            
+            for ( OrganisationUnit unit : units )
+            {
+                mapLayer.addBoundaryMapObject( unit );
+            }
+        }
+        else // Thematic layer
+        {
+            Collection<MapValue> mapValues = getAggregatedMapValues( mapView );
+    
+            if ( mapValues.isEmpty() )
+            {
+                return null;
+            }
+            
+            // Build and set the internal GeoTools map objects for the layer
+            
+            for ( MapValue mapValue : mapValues )
+            {
+                // Get the org unit for this map value
+                OrganisationUnit orgUnit = uidOuMap.get( mapValue.getOu() );
+                
+                if ( orgUnit != null && orgUnit.hasCoordinates() && orgUnit.hasFeatureType() )
+                {
+                    mapLayer.addDataMapObject( mapValue.getValue(), orgUnit );
+                }
+            }
+    
+            // Create an interval set for this map layer that distributes its map
+            // objects into their respective intervals
+            
+            if ( hasLegendSet )
+            {
+                mapLayer.setIntervalSetFromLegendSet( mapView.getLegendSet() );
+                mapLayer.distributeAndUpdateMapObjectsInIntervalSet();
+            }
+            else
+            {
+                mapLayer.applyIntervalSetToMapLayer( DistributionStrategy.STRATEGY_EQUAL_RANGE, mapLayer.getClasses() );
+                mapLayer.distributeAndUpdateMapObjectsInIntervalSet();
+            }
+            
+            // Update the radius of each map object in this map layer according to
+            // its map object's highest and lowest values
+            
+            if ( !isIndicator )
+            {
+                mapLayer.applyInterpolatedRadii();
+            }
         }
 
         return mapLayer;
     }
     
     /**
+     * Returns a list of map values for the given map view. If the map view is
+     * not a data layer, an empty list is returned.
+     */
+    private List<MapValue> getAggregatedMapValues( MapView mapView )
+    {
+        DataQueryParams params = analyticsService.getFromAnalyticalObject( mapView, null );
+        
+        Grid grid = analyticsService.getAggregatedDataValues( params );
+
+        return getMapValues( grid );
+    }
+    
+    /**
      * Creates a list of aggregated map values.
      */
     private List<MapValue> getMapValues( Grid grid )

=== modified file 'dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/InternalMapLayer.java'
--- dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/InternalMapLayer.java	2013-10-06 20:38:51 +0000
+++ dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/InternalMapLayer.java	2013-10-06 22:11:27 +0000
@@ -61,9 +61,9 @@
 
     protected Period period;
 
-    protected int radiusHigh;
+    protected Integer radiusHigh;
 
-    protected int radiusLow;
+    protected Integer radiusLow;
 
     protected Color colorHigh;
 
@@ -144,29 +144,42 @@
      * on the map object.
      * 
      * @param mapValue the map values to set on the map object.
-     * @param orgUnit the organisation unit which name to set on the map object.
+     * @param unit the organisation unit which name to set on the map object.
      */
-    public void addSingleGeoToolsMapObject( double mapValue, OrganisationUnit orgUnit )
+    public void addDataMapObject( double mapValue, OrganisationUnit unit )
     {
-        // Create and setup an internal map object
         InternalMapObject mapObject = new InternalMapObject();
-        mapObject.setName( orgUnit.getName() );
+        
+        mapObject.setName( unit.getName() );
         mapObject.setValue( mapValue );
         mapObject.setFillOpacity( opacity );
         mapObject.setStrokeColor( strokeColor );
         mapObject.setStrokeWidth( strokeWidth );
 
-        // Build and set the GeoTools-specific geometric primitive that outlines
-        // the org unit on the map
-        mapObject.setGeometry( InternalMapObject.buildAndApplyGeometryForOrganisationUnit( orgUnit ) );
+        // Build and set the geometric primitive that outlines org unit on the map
+        mapObject.setGeometry( InternalMapObject.buildAndApplyGeometryForOrganisationUnit( unit ) );
 
         // Add the map object to the map layer
-        this.addMapObject( mapObject );
+        addMapObject( mapObject );
 
         // Set the map layer for the map object
         mapObject.setMapLayer( this );
     }
+    
+    public void addBoundaryMapObject( OrganisationUnit unit )
+    {
+        InternalMapObject mapObject = new InternalMapObject();
+        
+        mapObject.setName( unit.getName() );
+        mapObject.setFillOpacity( opacity );
+        mapObject.setStrokeColor( Color.BLACK );
+        mapObject.setStrokeWidth( 1 );
 
+        mapObject.setGeometry( InternalMapObject.buildAndApplyGeometryForOrganisationUnit( unit ) );
+        addMapObject( mapObject );
+        mapObject.setMapLayer( this );
+    }
+    
     /**
      * Sets an interval set on this map layer based on the given legend set.
      * 
@@ -349,22 +362,22 @@
         this.period = period;
     }
 
-    public int getRadiusHigh()
+    public Integer getRadiusHigh()
     {
         return radiusHigh;
     }
 
-    public void setRadiusHigh( int radiusHigh )
+    public void setRadiusHigh( Integer radiusHigh )
     {
         this.radiusHigh = radiusHigh;
     }
 
-    public int getRadiusLow()
+    public Integer getRadiusLow()
     {
         return radiusLow;
     }
 
-    public void setRadiusLow( int radiusLow )
+    public void setRadiusLow( Integer radiusLow )
     {
         this.radiusLow = radiusLow;
     }

=== modified file 'dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/InternalMapObject.java'
--- dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/InternalMapObject.java	2013-10-06 17:01:11 +0000
+++ dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/InternalMapObject.java	2013-10-06 22:11:27 +0000
@@ -29,6 +29,7 @@
  */
 
 import java.awt.Color;
+import java.io.IOException;
 
 import org.geotools.data.DataUtilities;
 import org.geotools.feature.SchemaException;
@@ -154,9 +155,9 @@
             JsonParser parser = new ObjectMapper().getJsonFactory().createJsonParser( coords );
             root = parser.readValueAsTree();
         }
-        catch ( Exception ex )
+        catch ( IOException ex )
         {
-            throw new RuntimeException( ex );
+            throw new RuntimeException( "Failed to parse JSON", ex );
         }
 
         // Use the factory to build the correct type based on the feature type

=== modified file 'dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/Legend.java'
--- dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/Legend.java	2013-10-06 17:01:11 +0000
+++ dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/Legend.java	2013-10-06 22:11:27 +0000
@@ -31,7 +31,7 @@
 import java.awt.Color;
 import java.awt.Font;
 import java.awt.Graphics2D;
-import java.util.LinkedList;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -57,7 +57,7 @@
     public Legend( InternalMapLayer mapLayer )
     {
         this.mapLayer = mapLayer;
-        this.legendItems = new LinkedList<LegendItem>();
+        this.legendItems = new ArrayList<LegendItem>();
 
         for ( Interval interval : mapLayer.getIntervalSet().getIntervals() )
         {

=== modified file 'dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/LegendSet.java'
--- dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/LegendSet.java	2013-08-23 16:05:01 +0000
+++ dhis-2/dhis-services/dhis-service-mapgeneration/src/main/java/org/hisp/dhis/mapgeneration/LegendSet.java	2013-10-06 22:11:27 +0000
@@ -32,7 +32,7 @@
 import java.awt.Graphics2D;
 import java.awt.RenderingHints;
 import java.awt.image.BufferedImage;
-import java.util.LinkedList;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -55,18 +55,18 @@
 
     public LegendSet()
     {
-        legends = new LinkedList<Legend>();
+        legends = new ArrayList<Legend>();
     }
 
     public LegendSet( InternalMapLayer mapLayer )
     {
-        legends = new LinkedList<Legend>();
+        legends = new ArrayList<Legend>();
         addMapLayer( mapLayer );
     }
 
     public LegendSet( List<InternalMapLayer> mapLayers )
     {
-        legends = new LinkedList<Legend>();
+        legends = new ArrayList<Legend>();
         addMapLayers( mapLayers );
     }