def post(self, request, *args, **kwargs): if request.is_ajax(): cur_shp_id = kwargs['pk'] # calculate area as GEOS object using convex hull operation, # save it, calculate area value, save it in db as geometry attribute cur_shp = Shapefile.objects.get(id=cur_shp_id) cur_shp_geom = get_geos_geometry(cur_shp) area_geom = GEOSGeometry(cur_shp_geom.convex_hull) # calculates the area and update the db entry area_geom.set_srid(4326) # get measure in Google Mercator proj area_geom.transform(3857) # ibidem # get area value in Shapefile's projection proj_area_geom = area_geom proj_area_geom.transform(cur_shp.proj) # save the new GEOS area to geometry in db new_area = HelperSettlementArea(shapefile_id=cur_shp_id, poly=area_geom, storedarea=proj_area_geom.area) new_area.save() cur_shp.stat_sett_area = True cur_shp.save() context = context_results(cur_shp_id) return render_to_response( 'appgeostat/shp_detail_table.html', {'context': context})
def from_json(self, data): try: try: geom = GEOSGeometry(str(data.geometry)) if(hasattr(data.geometry.crs, 'properties')): crs = data.geometry.crs.properties['name'] srs = SpatialReference(crs) geom.set_srid(srs.srid) geom.transform(4326) self.geom = geom except: return None, "Invalid Geometry" if('project_id' in data.__dict__['properties']): try: self.project = Project.objects.get(id=int(data.__dict__['properties']['project_id'])) except (ValueError, ObjectDoesNotExist): return None, "Invalid Project" else: return None, "Project is required" if('name' in data.__dict__['properties']): self.name = data.__dict__['properties']['name'] else: return None, "Name is Required" self.save() return self, None except: return None, "Unexpected Error"
def to_geos(json_dict_polygon): """Return GEOSGeometry polygon from polygon dictionary""" json_dict_polygon = json_dict_polygon['geometry'] geo = GEOSGeometry(dump_json(json_dict_polygon)) geo.set_srid(original_project) geo.transform(desired_projection) return geo
def manipulate(self): #extract target_shape geometry target_shape = self.target_to_valid_geom(self.target_shape) #extract diff_geom geometry try: diff_geom = GEOSGeometry(self.diff_geom) diff_geom.set_srid(settings.GEOMETRY_CLIENT_SRID) except Exception as e: raise self.InternalException( "Exception raised in DifferenceFromShapeManipulator while initializing geometry on self.diff_geom: " + e.message) if not diff_geom.valid: raise self.InternalException( "DifferenceFromShapeManipulator: 'diff_geom' is not a valid geometry" ) #determine the difference in the two geometries try: clipped_shape = target_shape.difference(diff_geom) except Exception as e: raise self.InternalException( "Exception raised in DifferenceFromShapeManipulator while intersecting geometries: " + e.message) #if there is no geometry left (difference was empty) if clipped_shape.area <= self.zero: status_html = self.do_template("2") message = "difference resulted in empty geometry" raise self.HaltManipulations(message, status_html) #if there was overlap largest_poly = LargestPolyFromMulti(clipped_shape) status_html = self.do_template("0") return self.result(largest_poly, status_html)
def from_json(self, data): try: try: geom = GEOSGeometry(str(data.geometry)) if(hasattr(data.geometry.crs, 'properties')): crs = data.geometry.crs.properties['name'] srs = SpatialReference(crs) geom.set_srid(srs.srid) geom.transform(4326) ls = LineString(geom[0].coords) if(ls.simple == False): return None, 'Error Creating Geometry: Polygon is not Valid' self.geom = geom except: logger.debug(sys.exc_info()) return None, 'Error Creating Geometry' if('name' in data.__dict__['properties']): self.name = data.__dict__['properties']['name'] else: return None, 'Name is required' if('max_area' in data.__dict__['properties']): try: self.max_area = int(data.__dict__['properties']['max_area']) except ValueError: return None, 'Invalid Max Area' else: return None, 'Max Area is Required' self.save() return self, None except: # ToDo catch errors specifically and return message/code return None, 'Unknown'
def search_catalog(request, *args, **kwargs): """A spatial search for the DataResource catalog. In the future, this will be more thorough, but right now it looks for a filter parameter in the request, and inside that a JSON payload including a bbox four-tuple of minx, maxx miny, maxy OR a geometry wkt and an optional srid. It then performs a broad overlap search and returns the results as a JSON or JSONP list of:: [{ "title" : "title", "path" : ["breadcrumps", "to", "resource"], "url" : "http://mydomain/ga_resources/path/to/resource/title" }] """ flt = json.loads(request.REQUEST['filter']) if 'bbox' in flt: minx, miny, maxx, maxy = flt['bbox'] geometry = Polygon.from_bbox((minx, miny, maxx, maxy)) else: geometry = GEOSGeometry(flt['boundary']) if 'srid' in flt: geometry.set_srid(flt['srid']) results = DataResource.objects.filter(bounding_box__overlaps=geometry) ret = [{'title': r.title, 'path': r.slug.split('/')[:-1], 'url': r.get_abolute_url()} for r in results] callback = None if 'jsonCallback' in request.REQUEST: callback = request.REQUEST['jsonCallback'] elif 'callback' in request.REQUEST: callback = request.REQUEST['callback'] if callback: return HttpResponse(callback + '(' + json.dumps(ret) + ")", mimetype='text/plain') else: return HttpResponse(json.dumps(ret), mimetype='application/json')
def manipulate(self): #extract target_shape geometry target_shape = self.target_to_valid_geom(self.target_shape) #extract diff_geom geometry try: diff_geom = GEOSGeometry(self.diff_geom) diff_geom.set_srid(settings.GEOMETRY_CLIENT_SRID) except Exception, e: raise self.InternalException("Exception raised in DifferenceFromShapeManipulator while initializing geometry on self.diff_geom: " + e.message)
def manipulate(self): #extract target_shape geometry target_shape = self.target_to_valid_geom(self.target_shape) #extract clip_against geometry try: clip_against = GEOSGeometry(self.clip_against) clip_against.set_srid(settings.GEOMETRY_CLIENT_SRID) except Exception, e: raise self.InternalException("Exception raised in ClipToShapeManipulator while initializing geometry on self.clip_against: " + e.message)
def manipulate(self): #extract target_shape geometry target_shape = self.target_to_valid_geom(self.target_shape) #extract study_region geometry #study_region argument is FOR UNIT-TESTING PURPOSES ONLY, otherwise we access the database if self.study_region is not None: try: study_region = GEOSGeometry(self.study_region) study_region.set_srid(settings.GEOMETRY_CLIENT_SRID) study_region.transform(settings.GEOMETRY_DB_SRID) except Exception, e: raise self.InternalException("Exception raised in ClipToStudyRegionManipulator while initializing study region geometry: " + e.message)
def manipulate(self): #extract target_shape geometry target_shape = self.target_to_valid_geom(self.target_shape) #extract study_region geometry #study_region argument is FOR UNIT-TESTING PURPOSES ONLY, otherwise we access the database if self.study_region is not None: try: study_region = GEOSGeometry(self.study_region) study_region.set_srid(settings.GEOMETRY_CLIENT_SRID) study_region.transform(settings.GEOMETRY_DB_SRID) except Exception as e: raise self.InternalException( "Exception raised in ClipToStudyRegionManipulator while initializing study region geometry: " + e.message) else: try: study_region = StudyRegion.objects.current().geometry except Exception as e: raise self.InternalException( "Exception raised in ClipToStudyRegionManipulator while obtaining study region geometry from database: " + e.message) #intersect the two geometries try: target_shape.transform(settings.GEOMETRY_DB_SRID) clipped_shape = target_shape.intersection(study_region) target_shape.transform(settings.GEOMETRY_CLIENT_SRID) clipped_shape.transform(settings.GEOMETRY_CLIENT_SRID) except Exception as e: raise self.InternalException( "Exception raised in ClipToStudyRegionManipulator while intersecting geometries: " + e.message) out_geom = None if target_shape.geom_type == 'Polygon' and clipped_shape.area > 0: out_geom = LargestPolyFromMulti(clipped_shape) elif target_shape.geom_type == 'LineString' and clipped_shape.length > 0: out_geom = LargestLineFromMulti(clipped_shape) elif target_shape.geom_type == 'Point' and not clipped_shape.empty: out_geom = clipped_shape if out_geom is None: message = "clipped geometry is empty (there was no intersection/overlap with study region)" status_html = self.do_template("2") raise self.HaltManipulations(message, status_html) status_html = self.do_template("0") return self.result(out_geom, status_html)
def target_to_valid_geom(self, shape): try: if iskml(shape): target = parsekml(shape) else: target = GEOSGeometry(shape) except Exception as e: raise self.InvalidGeometryException(e.message) if not target.valid: target = target.buffer(0) if not target.valid: raise self.InvalidGeometryException() target.set_srid(settings.GEOMETRY_CLIENT_SRID) return target
def search_catalog(request, *args, **kwargs): """A spatial search for the DataResource catalog. In the future, this will be more thorough, but right now it looks for a filter parameter in the request, and inside that a JSON payload including a bbox four-tuple of minx, maxx miny, maxy OR a geometry wkt and an optional srid. It then performs a broad overlap search and returns the results as a JSON or JSONP list of:: [{ "title" : "title", "path" : ["breadcrumps", "to", "resource"], "url" : "http://mydomain/ga_resources/path/to/resource/title" }] """ flt = json.loads(request.REQUEST['filter']) if 'bbox' in flt: minx, miny, maxx, maxy = flt['bbox'] geometry = Polygon.from_bbox((minx, miny, maxx, maxy)) else: geometry = GEOSGeometry(flt['boundary']) if 'srid' in flt: geometry.set_srid(flt['srid']) results = DataResource.objects.filter(bounding_box__overlaps=geometry) ret = [{ 'title': r.title, 'path': r.slug.split('/')[:-1], 'url': r.get_abolute_url() } for r in results] callback = None if 'jsonCallback' in request.REQUEST: callback = request.REQUEST['jsonCallback'] elif 'callback' in request.REQUEST: callback = request.REQUEST['callback'] if callback: return HttpResponse(callback + '(' + json.dumps(ret) + ")", mimetype='text/plain') else: return HttpResponse(json.dumps(ret), mimetype='application/json')
def manipulate(self): #extract target_shape geometry target_shape = self.target_to_valid_geom(self.target_shape) #extract clip_against geometry try: clip_against = GEOSGeometry(self.clip_against) clip_against.set_srid(settings.GEOMETRY_CLIENT_SRID) except Exception as e: raise self.InternalException( "Exception raised in ClipToShapeManipulator while initializing geometry on self.clip_against: " + e.message) if not clip_against.valid: raise self.InternalException( "ClipToShapeManipulator: 'clip_against' is not a valid geometry" ) #intersect the two geometries try: clipped_shape = target_shape.intersection(clip_against) except Exception as e: raise self.InternalException( "Exception raised in ClipToShapeManipulator while intersecting geometries: " + e.message) #if there was no overlap (intersection was empty) if clipped_shape.area <= self.zero: status_html = self.do_template("2") message = "intersection resulted in empty geometry" # ALTERATION #1 #return self.result(clipped_shape, target_shape, status_html, message) raise self.HaltManipulations(message, status_html) # ALTERATION #2 #if there was overlap largest_poly = LargestPolyFromMulti(clipped_shape) status_html = self.do_template("0") #message = "'target_shape' was clipped successfully to 'clip_against'" #return self.result(largest_poly, target_shape, status_html, message) return self.result(largest_poly, status_html)
def to_geom(string): """ Given a string, convert it to a geometry. """ try: geom = GEOSGeometry(string) except ValueError: try: lat, lng = [float(coord.strip()) for coord in string.split(',')] except ValueError: raise ValueError( ('Argument must be a comma-separated pair of numbers or a ' 'string that the GEOSGeometry constructor can handle: %r') % string ) else: geom = Point(lng, lat) # Assume WGS84 (lat/lng) if no SRID is attached yet. if not geom.srid: geom.set_srid(4326) return geom
def from_json(self, data): try: try: geom = GEOSGeometry(str(data.geometry)) if(hasattr(data.geometry.crs, 'properties')): crs = data.geometry.crs.properties['name'] srs = SpatialReference(crs) geom.set_srid(srs.srid) geom.transform(4326) # Topology Checks # - Is LinearRing (simple polygon, doesnt intersect itself) ls = LineString(geom[0].coords) if(ls.simple == False): return None, 'Error Creating Geometry: Polygon is not Valid' self.geom = geom except: return None, "Invalid Geometry" if('type' in data.__dict__['properties']): try: type = int(data.__dict__['properties']['type']) if(type in [1,2,3,4]): self.type = type else: return None, "Invalid Type" except ValueError: return None, "Invalid Type" else: return None, "Type is Required" if("project_id" in data.__dict__['properties']): try: project_id = data.__dict__['properties']['project_id'] self.project = Project.objects.get(id=int(project_id)) # Topology Check # - verify that the internal polygon is completely within the project polygon if(self.project.geom.contains(self.geom) == False): return None, 'Error Creating Geometry: Internal Polygon not Within Project Polygon' except (ValueError, ObjectDoesNotExist): return None, "Invalid Project" else: return None, "Project is Required" # Topology Check # - verify that the internal polygon doesnt intersect any other internal polygons for this project xip = InternalPolygon.objects.filter(project=self.project, geom__intersects=geom) if(xip.count() > 0): for ip in xip: if(self.geom.contains(ip.geom) == False and self.geom.within(ip.geom) == False): if(ip.type == 3 or self.type == 3): if(self.type == 3 and ip.type == 3): return None, 'Error Creating Geometry: AOI Polygons cannot intersect other AOIs' else: return None, 'Error Creating Geometry: Polygon Intersects other Polygons' if("value" in data.__dict__['properties']): try: self.value = float(data.__dict__['properties']['value']) except ValueError: return None, "Invalid Value" else: if(self.type != 3): # Value is not required for AOI return None, "Value is Required" self.save() return self, None except: return None, "Unexpected Error"