def kml_chunk(self, n, s, e, w): """ Get the kml of a lat/lon bounded part of the study region, with geometry simplified in proportion to the visible % of the region """ bounds = Polygon(LinearRing([Point(w, n), Point(e, n), Point(e, s), Point(w, s), Point(w, n)])) bounds.set_srid(4326) center_lat = bounds.centroid.y # in 4326 because it is used only for setting up the subregion calls center_lon = bounds.centroid.x # in 4326 because it is used only for setting up the subregion calls bounds.transform(settings.GEOMETRY_DB_SRID) # all longitudinal width calcs should be done in GEOMETRY_DB_SRID - 4326 can fail across the date line zoom_width = (Point(bounds.extent[0], bounds.centroid.y)).distance(Point(bounds.extent[2], bounds.centroid.y)) full_shape_width = (Point(self.geometry.extent[0], self.geometry.centroid.y)).distance(Point(self.geometry.extent[2], self.geometry.centroid.y)) # The following simplify values can be tuned to your preference # minimum geometry simplify value (highest detail) = 50 (arbitrary, based on observation) # maximum geometry simplify value = 200 (arbitrary, based on observation) # value set by pecentage of study region width requested in this chunk min_simplify_val = 50.0 max_simplify_val = 200.0 simplify_factor = max(min_simplify_val, min(max_simplify_val, max_simplify_val * zoom_width / full_shape_width)) transform_geom = self.geometry.simplify(simplify_factor, preserve_topology=True) transform_geom = transform_geom.intersection(bounds) transform_geom.transform(4326) # Debugging info #print zoom_width #print full_shape_width #print simplify_factor #print transform_geom.num_coords # End debugging info # only add sub-regions if this is not our highest detail level bLastLodLevel = simplify_factor < max_simplify_val # change this last value to build varying levels of LOD max_lod_pixels = 500 min_lod_pixels = 250 # make sure the most detailed lod stays active no matter how close user zooms if bLastLodLevel: max_lod_pixels = -1 retval = '<Region><LatLonAltBox><north>%f</north><south>%f</south><east>%f</east><west>%f</west></LatLonAltBox><Lod><minLodPixels>%f</minLodPixels><maxLodPixels>%f</maxLodPixels><minFadeExtent>0</minFadeExtent><maxFadeExtent>0</maxFadeExtent></Lod></Region>' % (n, s, e, w, min_lod_pixels, max_lod_pixels) + '<Placemark> <name>Study Region Boundaries</name><Style> <LineStyle> <color>ff00ffff</color> <width>2</width> </LineStyle> <PolyStyle> <color>8000ffff</color> </PolyStyle></Style>%s</Placemark>' % (transform_geom.kml,) # conditionally add sub-regions if not bLastLodLevel: subregions = '<Folder><name>Study Region LODs</name>' + '<Folder><name>SE</name>' + self.kml_chunk(center_lat, s, e, center_lon) + '</Folder>' subregions = subregions + '<Folder><name>NE</name>' + self.kml_chunk(n, center_lat, e, center_lon) + '</Folder>' subregions = subregions + '<Folder><name>SW</name>' + self.kml_chunk(center_lat, s, center_lon, w) + '</Folder>' subregions = subregions + '<Folder><name>NW</name>' + self.kml_chunk(n, center_lat, center_lon, w) + '</Folder>' retval = retval + subregions + '</Folder>' return retval
def build_box(self): """ top_left = (west, north) top_right = (east, north) bottom_right = (east, south) bottom_left = (west, south) """ try: box = Polygon( LinearRing( [ Point(float(self.west), float(self.north)), Point(float(self.east), float(self.north)), Point(float(self.east), float(self.south)), Point(float(self.west), float(self.south)), Point(float(self.west), float(self.north)), ] ) ) box.set_srid(settings.GEOMETRY_CLIENT_SRID) return box except Exception, e: raise self.InternalException( "Exception raised in ClipToGraticuleManipulator while initializing graticule geometry: " + e.message )
def build_box(self): ''' top_left = (west, north) top_right = (east, north) bottom_right = (east, south) bottom_left = (west, south) ''' try: box = Polygon( LinearRing([ Point( float(self.west), float(self.north) ), Point( float(self.east), float(self.north) ), Point( float(self.east), float(self.south) ), Point( float(self.west), float(self.south) ), Point( float(self.west), float(self.north))])) box.set_srid(settings.GEOMETRY_CLIENT_SRID) return box except Exception, e: raise self.InternalException("Exception raised in ClipToGraticuleManipulator while initializing graticule geometry: " + e.message)
def kml_chunk(self, n, s, e, w): """ Get the kml of a lat/lon bounded part of the study region, with geometry simplified in proportion to the visible % of the region """ bounds = Polygon( LinearRing([ Point(w, n), Point(e, n), Point(e, s), Point(w, s), Point(w, n) ])) bounds.set_srid(4326) center_lat = bounds.centroid.y # in 4326 because it is used only for setting up the subregion calls center_lon = bounds.centroid.x # in 4326 because it is used only for setting up the subregion calls bounds.transform(settings.GEOMETRY_DB_SRID) # all longitudinal width calcs should be done in GEOMETRY_DB_SRID - 4326 can fail across the date line zoom_width = (Point(bounds.extent[0], bounds.centroid.y)).distance( Point(bounds.extent[2], bounds.centroid.y)) full_shape_width = (Point(self.geometry.extent[0], self.geometry.centroid.y)).distance( Point(self.geometry.extent[2], self.geometry.centroid.y)) # The following simplify values can be tuned to your preference # minimum geometry simplify value (highest detail) = 50 (arbitrary, based on observation) # maximum geometry simplify value = 200 (arbitrary, based on observation) # value set by pecentage of study region width requested in this chunk min_simplify_val = 50.0 max_simplify_val = 200.0 simplify_factor = max( min_simplify_val, min(max_simplify_val, max_simplify_val * zoom_width / full_shape_width)) transform_geom = self.geometry.simplify(simplify_factor, preserve_topology=True) transform_geom = transform_geom.intersection(bounds) transform_geom.transform(4326) # Debugging info #print zoom_width #print full_shape_width #print simplify_factor #print transform_geom.num_coords # End debugging info # only add sub-regions if this is not our highest detail level bLastLodLevel = simplify_factor < max_simplify_val # change this last value to build varying levels of LOD max_lod_pixels = 500 min_lod_pixels = 250 # make sure the most detailed lod stays active no matter how close user zooms if bLastLodLevel: max_lod_pixels = -1 retval = '<Region><LatLonAltBox><north>%f</north><south>%f</south><east>%f</east><west>%f</west></LatLonAltBox><Lod><minLodPixels>%f</minLodPixels><maxLodPixels>%f</maxLodPixels><minFadeExtent>0</minFadeExtent><maxFadeExtent>0</maxFadeExtent></Lod></Region>' % ( n, s, e, w, min_lod_pixels, max_lod_pixels ) + '<Placemark> <name>Study Region Boundaries</name><Style> <LineStyle> <color>ff00ffff</color> <width>2</width> </LineStyle> <PolyStyle> <color>8000ffff</color> </PolyStyle></Style>%s</Placemark>' % ( transform_geom.kml, ) # conditionally add sub-regions if not bLastLodLevel: subregions = '<Folder><name>Study Region LODs</name>' + '<Folder><name>SE</name>' + self.kml_chunk( center_lat, s, e, center_lon) + '</Folder>' subregions = subregions + '<Folder><name>NE</name>' + self.kml_chunk( n, center_lat, e, center_lon) + '</Folder>' subregions = subregions + '<Folder><name>SW</name>' + self.kml_chunk( center_lat, s, center_lon, w) + '</Folder>' subregions = subregions + '<Folder><name>NW</name>' + self.kml_chunk( n, center_lat, center_lon, w) + '</Folder>' retval = retval + subregions + '</Folder>' return retval