def _get_shape(self, value): points = json.loads(value) # close ring and create Polygon polygon = Polygon(points+[points[0]]) polygon.srid = SRID_WSG84 polygon.transform(SRID_RD) return polygon
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 test_native_writer(self): values = { "identifier": "some_unique_id", "begin_time": datetime(2013, 8, 27, 10, 0, 0, tzinfo=utc), "end_time": datetime(2013, 8, 27, 10, 0, 10, tzinfo=utc), "footprint": MultiPolygon( Polygon.from_bbox((0, 0, 10, 20)), Polygon.from_bbox((10, 10, 30, 40)) ) } writer = native.NativeFormat(env) f = StringIO() writer.write(values, f, pretty=True) self.assertEqual(dedent("""\ <Metadata> <EOID>some_unique_id</EOID> <BeginTime>2013-08-27T10:00:00Z</BeginTime> <EndTime>2013-08-27T10:00:10Z</EndTime> <Footprint> <Polygon> <Exterior>0.000000 0.000000 20.000000 0.000000 20.000000 10.000000 0.000000 10.000000 0.000000 0.000000</Exterior> </Polygon> <Polygon> <Exterior>10.000000 10.000000 40.000000 10.000000 40.000000 30.000000 10.000000 30.000000 10.000000 10.000000</Exterior> </Polygon> </Footprint> </Metadata> """), dedent(f.getvalue()))
def build_filters(self, filters=None): if filters is None: filters = {} applicable_filters = {} # Normal filtering filter_params = dict([(x, filters[x]) for x in filters if not x.startswith('!')]) applicable_filters['filter'] = super(HutSearchResource, self).build_filters(filter_params) # Exclude filtering exclude_params = dict([(x[1:], filters[x]) for x in filters if x.startswith('!')]) applicable_filters['exclude'] = super(HutSearchResource, self).build_filters(exclude_params) # Custom bounds filter if 'bounds' in filters: bounds = filters['bounds'] lat_lo, lng_lo, lat_hi, lng_hi = [float(x) for x in bounds.split(',')] # latitude first from request, longitude first for database! if lng_lo > 0 and lng_hi < 0: p1 = Polygon.from_bbox((lng_lo, lat_lo, 180, lat_hi)) p2 = Polygon.from_bbox((-180, lat_lo, lng_hi, lat_hi)) polygon = MultiPolygon(p1, p2) else: polygon = Polygon.from_bbox((lng_lo, lat_lo, lng_hi, lat_hi)) applicable_filters['filter']['location__within'] = polygon return applicable_filters
def compute_spatial_metadata(self, **kwargs): """Other keyword args get passed in as a matter of course, like BBOX, time, and elevation, but this basic driver ignores them""" super(OGRDriver, self).compute_spatial_metadata(**kwargs) # if we have a zip archive, we should expand it now archive_filename = self.get_filename('zip') if os.path.exists(archive_filename): archive = ZipFile(self.cached_basename + self.src_ext) os.mkdir(self.cached_basename) # we will put everything cached underneath the cached base directory archive.extractall(self.cached_basename) ds = ogr.Open(self.get_master_filename()) lyr = ds.GetLayerByIndex(0) if 'sublayer' not in kwargs else ds.GetLayerByName(kwargs['sublayer']) xmin, xmax, ymin, ymax = lyr.GetExtent() crs = lyr.GetSpatialRef() self.resource.spatial_metadata.native_srs = crs.ExportToProj4() e4326 = osr.SpatialReference() e4326.ImportFromEPSG(4326) crx = osr.CoordinateTransformation(crs, e4326) x04326, y04326, _ = crx.TransformPoint(xmin, ymin) x14326, y14326, _ = crx.TransformPoint(xmax, ymax) self.resource.spatial_metadata.bounding_box = Polygon.from_bbox((x04326, y04326, x14326, y14326)) self.resource.spatial_metadata.native_bounding_box = Polygon.from_bbox((xmin, ymin, xmax, ymax)) self.resource.spatial_metadata.three_d = False self.resource.spatial_metadata.save() self.resource.save()
def setUp(self): # Make sure we're using the GB postcode functions here models.countries = countries utils.countries = countries self.postcode = models.Postcode.objects.create( postcode='SW1A1AA', location=Point(-0.141588, 51.501009) ) self.generation = models.Generation.objects.create( active=True, description="Test generation", ) self.type = models.Type.objects.create( code="TEST_TYPE", description="A test area", ) self.area = models.Area.objects.create( name="Area", type=self.type, generation_low=self.generation, generation_high=self.generation, ) polygon = Polygon(((-5, 50), (-5, 55), (1, 55), (1, 50), (-5, 50)), srid=4326) polygon.transform(settings.MAPIT_AREA_SRID) self.shape = models.Geometry.objects.create( area=self.area, polygon=polygon, )
def test_native_reader(self): xml = """ <Metadata> <EOID>some_unique_id</EOID> <BeginTime>2013-08-27T10:00:00Z</BeginTime> <EndTime>2013-08-27T10:00:10Z</EndTime> <Footprint> <Polygon> <Exterior>0 0 20 0 20 10 0 10 0 0</Exterior> <!--<Interior></Interior>--> </Polygon> <Polygon> <Exterior>10 10 40 10 40 30 10 30 10 10</Exterior> <!--<Interior></Interior>--> </Polygon> </Footprint> </Metadata> """ reader = native.NativeFormat(env) self.assertTrue(reader.test(xml)) values = reader.read(xml) self.assertEqual({ "identifier": "some_unique_id", "begin_time": datetime(2013, 8, 27, 10, 0, 0, tzinfo=utc), "end_time": datetime(2013, 8, 27, 10, 0, 10, tzinfo=utc), "footprint": MultiPolygon( Polygon.from_bbox((0, 0, 10, 20)), Polygon.from_bbox((10, 10, 30, 40)) ) }, values)
def compute_spatial_metadata(self, **kwargs): """Other keyword args get passed in as a matter of course, like BBOX, time, and elevation, but this basic driver ignores them""" self.cache_data_file(True) ds = gdal.Open(self.cached_basename + '.tif') nx = ds.RasterXSize ny = ds.RasterYSize x0, dx, _, y0, _, dy = ds.GetGeoTransform() xmin, xmax, ymin, ymax = ( x0, x0+dx*nx, y0 if dy > 0 else y0 + dy*ny, y0 + dy*ny if dy > 0 else y0 ) crs = osr.SpatialReference() crs.ImportFromWkt(ds.GetProjection()) self.resource.spatial_metadata.native_srs = crs.ExportToProj4() e4326 = osr.SpatialReference() e4326.ImportFromEPSG(4326) crx = osr.CoordinateTransformation(crs, e4326) x04326, y04326, _ = crx.TransformPoint(xmin, ymin) x14326, y14326, _ = crx.TransformPoint(xmax, ymax) self.resource.spatial_metadata.bounding_box = Polygon.from_bbox((x04326, y04326, x14326, y14326)) self.resource.spatial_metadata.native_bounding_box = Polygon.from_bbox((xmin, ymin, xmax, ymax)) self.resource.spatial_metadata.save() self.resource.save()
def generateGrid(self, size): ''' generate a grid overlaying the city :param size: dimension of the cell for the grid :rtype: an array of cells that forms the grid ''' file = 'city-{0}_size-{1}m.p'.format(self.name, size) path = settings.GRIDS_DIR + file grids = [] try: grids = pickle.load(open(path, "rb")) except EnvironmentError: start = Point(self.box['nw']['lon'], self.box['nw']['lat']) lat = lon = start while self.geom.envelope.intersects(lat): nw = lat ne = getNextPoint(nw, size, 90) sw = getNextPoint(nw, size, 180) se = getNextPoint(ne, size, 180) lat = ne linearRing = LinearRing(nw, ne, se, sw, nw) polygon = Polygon(linearRing) if polygon.intersects(self.geom): grids.append(polygon) if not self.geom.envelope.intersects(lat): lon = getNextPoint(lon, size, 180) lat = lon pickle.dump(grids, open(path, "wb")) return grids
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 setUp(self): self.generation = Generation.objects.create( active=True, description="Test generation", ) self.area_type = Type.objects.create( code="BIG", description="A large test area", ) self.name_type = NameType.objects.create( code='O', description='Ordnance Survey name type' ) self.area = Area.objects.create( name="Big Area", type=self.area_type, generation_low=self.generation, generation_high=self.generation, ) polygon = Polygon(((-5, 50), (-5, 55), (1, 55), (1, 50), (-5, 50)), srid=4326) polygon.transform(settings.MAPIT_AREA_SRID) self.geometry = self.area.polygons.create(polygon=polygon)
def add_anonymous_boundary(request): request_dict = json.loads(request.body) srid = request_dict.get('srid', 4326) polygon = Polygon(request_dict.get('polygon', []), srid=srid) if srid != 3857: polygon.transform(3857) b = Boundary.anonymous(polygon) b.save() return {'id': b.id}
def _extent(self, extents): union = None for extent in extents: if extent is not None: if union is None: union = Polygon.from_bbox(extent) else: union.union(Polygon.from_bbox(extent)) return None if union is None else union.extent
def _shape(points): if points[0] != points[-1]: points.append(points[0]) try: poly = Polygon([Point(*p, srid=OSGB) for p in points], srid=OSGB) poly.transform(WGS) return poly except Exception, e: print points print e raise
def database_add(request): """ Загрузка координат из *.kml в БД """ #Кооординаты Cornfield if request.method == 'POST': form = AddField(request.POST, request.FILES) if form.is_valid(): all_geometry = Cornfield.objects.filter(use_user = request.user) #fname = 'KML/' + request.FILES['append_field'].name[:-4] + "_" + str(request.user) + "_" + datetime.now().strftime("%d_%m_%Y_%H.%M.%S") + ".kml" fname = 'KML/' + str(request.user) + "_" + datetime.now().strftime("%d_%m_%Y_%H.%M.%S") + ".kml" f = open(os.path.join(MEDIA_ROOT, fname), 'wb+') for chunk in request.FILES['append_field'].chunks(): f.write(chunk) f.close() try: ds = DataSource(os.path.join(MEDIA_ROOT, fname)) #ds = DataSource(os.path.join(MEDIA_ROOT, 'ag_fields3.kml')) layer = ds[0] i = 0 for feat in layer: geom = feat.geom #print geom if geom: new_line = [] for line in geom: new_point = [] for point in line: new_point.append(Point(point[0],point[1])) new_point.append(new_point[0]) new_line = LinearRing(new_point) if not new_line.ring: new_point.append(new_point[0]) new_line = LinearRing(new_point) name = "e%d"%i poly = Polygon(new_line) polygon_equals = True for geom in all_geometry: if poly.equals_exact(geom.mpoly[0], 0.001): polygon_equals = False break if polygon_equals: c = Cornfield(use_user = request.user, name_field=name, area = round(poly.area*1000000,2), mpoly = MultiPolygon(poly), mpoly_coding_paths = encode_pairs(new_line)[0], mpoly_coding_levels = encode_pairs(new_line)[1]) c.save() i+=1 except: pass return redirect('show_map')
def test_polygons_from_bbox(self): "Testing `from_bbox` class method." bbox = (-180, -90, 180, 90) p = Polygon.from_bbox(bbox) self.assertEqual(bbox, p.extent) # Testing numerical precision x = 3.14159265358979323 bbox = (0, 0, 1, x) p = Polygon.from_bbox(bbox) y = p.extent[-1] self.assertEqual(format(x, ".13f"), format(y, ".13f"))
def validate_geom(geom, coordinate_count=0): try: coordinate_count += geom.num_coords bbox = Polygon(settings.DATA_VALIDATION_BBOX) if coordinate_count > coord_limit: message = 'Geometry has too many coordinates for Elasticsearch ({0}), Please limit to less then {1} coordinates of 5 digits of precision or less.'.format(coordinate_count, coord_limit) errors.append({'type': 'ERROR', 'message': 'datatype: {0} value: {1} {2} - {3}'.format(self.datatype_model.datatype, value, source, message)}) if bbox.contains(geom) == False: message = 'Geometry does not fall within the bounding box of the selected coordinate system. Adjust your coordinates or your settings.DATA_EXTENT_VALIDATION property.' except: message = 'Not a properly formatted geometry' errors.append({'type': 'ERROR', 'message': 'datatype: {0} value: {1} {2} - {3}'.format(self.datatype_model.datatype, value, source, message)})
def compute_spatial_metadata(self, **kwargs): """Other keyword args get passed in as a matter of course, like BBOX, time, and elevation, but this basic driver ignores them""" super(KmzDriver, self).compute_spatial_metadata(**kwargs) # archive = ZipFile(self.cached_basename + self.src_ext) srs = osr.SpatialReference() srs.ImportFromEPSG(4326) self.resource.native_srs = srs.ExportToProj4() self.resource.bounding_box = Polygon.from_bbox((-180, -90, 180, 90)) self.resource.native_bounding_box = Polygon.from_bbox((-180, -90, 180, 90)) self.resource.three_d = False self.resource.save()
def import_paths(filename): reader = shapefile.Reader(filename) records = reader.iterRecords() shapes = reader.iterShapes() cells = {} for record, shape in zip(records, shapes): id, x, y = record point = Point(x, y, srid=IN_SRID) point.transform(OUT_SRID) poly = Polygon(map(tuple, shape.points), srid=IN_SRID) poly.transform(OUT_SRID) cells[id] = Cell(id, point, poly) return cells
def setUp(self): self.generation = Generation.objects.create( active=True, description="Test generation", ) self.big_type = Type.objects.create( code="BIG", description="A large test area", ) self.small_type = Type.objects.create( code="SML", description="A small test area", ) self.big_area = Area.objects.create( name="Big Area", type=self.big_type, generation_low=self.generation, generation_high=self.generation, ) polygon = Polygon(((-5, 50), (-5, 55), (1, 55), (1, 50), (-5, 50)), srid=4326) polygon.transform(settings.MAPIT_AREA_SRID) self.big_shape = Geometry.objects.create( area=self.big_area, polygon=polygon) self.small_area_1 = Area.objects.create( name="Small Area 1", type=self.small_type, generation_low=self.generation, generation_high=self.generation, ) self.small_area_2 = Area.objects.create( name="Small Area 2", type=self.small_type, generation_low=self.generation, generation_high=self.generation, ) polygon = Polygon(((-4, 51), (-4, 52), (-3, 52), (-3, 51), (-4, 51)), srid=4326) polygon.transform(settings.MAPIT_AREA_SRID) self.small_shape_1 = Geometry.objects.create( area=self.small_area_1, polygon=polygon) polygon = Polygon(((-3, 51), (-3, 52), (-2, 52), (-2, 51), (-3, 51)), srid=4326) polygon.transform(settings.MAPIT_AREA_SRID) self.small_shape_2 = Geometry.objects.create( area=self.small_area_2, polygon=polygon) self.postcode = Postcode.objects.create( postcode='P', location=Point(-3.5, 51.5))
def compute_spatial_metadata(self, **kwargs): """Other keyword args get passed in as a matter of course, like BBOX, time, and elevation, but this basic driver ignores them""" super(PostGISDriver, self).compute_spatial_metadata(**kwargs) cfg = self.resource.driver_config connection = self._connection() xmin=ymin=float('inf') ymax=xmax=float('-inf') dataframe = self.get_filename('dfx') if os.path.exists(dataframe): os.unlink(dataframe) for entry in [cfg['table']] + cfg.get('tables', {}).values(): if isinstance(entry, list): table, geom_field = entry elif entry.startswith('#'): table, geom_field = self._table(sublayer=entry[1:]) else: table = entry geom_field = 'geometry' c = connection.cursor() c.execute("select AsText(st_extent({geom_field})) from {table}".format(geom_field=geom_field, table=table)) xmin0, ymin0, xmax0, ymax0 = GEOSGeometry(c.fetchone()[0]).extent xmin = xmin0 if xmin0 < xmin else xmin ymin = ymin0 if ymin0 < ymin else ymin xmax = xmax0 if xmax0 > xmax else xmax ymax = ymax0 if ymax0 > ymax else ymax crs = osr.SpatialReference() crs.ImportFromEPSG(cfg['srid']) self.resource.spatial_metadata.native_srs = crs.ExportToProj4() e4326 = osr.SpatialReference() e4326.ImportFromEPSG(4326) crx = osr.CoordinateTransformation(crs, e4326) x04326, y04326, _ = crx.TransformPoint(xmin, ymin) x14326, y14326, _ = crx.TransformPoint(xmax, ymax) print xmin, xmax, ymin, ymax print x04326, y04326, x14326, y14326 self.resource.spatial_metadata.bounding_box = Polygon.from_bbox((x04326, y04326, x14326, y14326)) self.resource.spatial_metadata.native_bounding_box = Polygon.from_bbox((xmin, ymin, xmax, ymax)) self.resource.spatial_metadata.three_d = False self.resource.spatial_metadata.save() self.resource.save()
def update_bounding_shape(self): ch = MultiPoint([e.location for e in self.photos.all()]).convex_hull # Point if ch.geom_typeid == 0: self.bounding_shape = Polygon.from_bbox((ch.coords[0], ch.coords[1], ch.coords[0], ch.coords[1])) # Polygon elif len(ch.coords[0]) > 2: self.bounding_shape = ch # Two-point line else: self.bounding_shape = Polygon.from_bbox((ch.coords[0][0], ch.coords[0][1], ch.coords[1][0], ch.coords[1][1])) self.bounding_shape_dirty = False self.save() return self.bounding_shape
def setUp(self,): self.path = os.path.dirname(os.path.realpath(__file__)) self.group, created = Group.objects.get_or_create(name="TestDefault") with patch('eventkit_cloud.jobs.signals.Group') as mock_group: mock_group.objects.get.return_value = self.group self.user = User.objects.create( username='******', email='*****@*****.**', password='******' ) bbox = Polygon.from_bbox((-10.85, 6.25, -10.62, 6.40)) tags = DatamodelPreset.objects.get(name='hdm').json_tags self.assertEqual(259, len(tags)) the_geom = GEOSGeometry(bbox, srid=4326) self.job = Job.objects.create( name='TestJob', description='Test description', user=self.user, the_geom=the_geom, json_tags=tags ) self.job.feature_save = True self.job.feature_pub = True self.job.save() self.run = ExportRun.objects.create(job=self.job, user=self.user)
def import_units(self): if not getattr(self, 'org_syncher', None): self.import_organizations(noop=True) if not getattr(self, 'dept_syncher', None): self.import_departments(noop=True) if self.options['single']: obj_id = self.options['single'] obj_list = [self.pk_get('unit', obj_id)] queryset = Unit.objects.filter(id=obj_id) else: obj_list = self.pk_get('unit') queryset = Unit.objects.all().select_related('services') self.target_srid = settings.PROJECTION_SRID self.bounding_box = Polygon.from_bbox(settings.BOUNDING_BOX) self.bounding_box.set_srid(4326) gps_srs = SpatialReference(4326) target_srs = SpatialReference(self.target_srid) target_to_gps_ct = CoordTransform(target_srs, gps_srs) self.bounding_box.transform(target_to_gps_ct) self.gps_to_target_ct = CoordTransform(gps_srs, target_srs) syncher = ModelSyncher(queryset, lambda obj: obj.id) for idx, info in enumerate(obj_list): self._import_unit(syncher, info) syncher.finish()
def get(self, request, *args, **kwargs): if 'in_bbox' not in request.GET: return JSONResponse(message="missing search area", _code=422) # Get cordinates for bbox from get parameter p1x, p1y, p2x, p2y = ( float(n) for n in request.GET.get('in_bbox').split(',') ) # Create min and max points with cordinates in EPSG:900913 for bbox p1 = Point(p1x, p1y, srid=900913) p2 = Point(p2x, p2y, srid=900913) # Transform EPSG:900913 (from OpenLayers) to EPSG:4326 (WGS64) p1.transform(4326) p2.transform(4326) # Create bbox which represents the visible map visible_map = Polygon.from_bbox( (p1.x, p1.y, p2.x, p2.y) ) # Is the visible map to big we don't response places if visible_map.area > 10: return JSONResponse(message="search area to big", _code=422) # Look for countries which are intersects by our visible map limited # by GET parameter or max value limit = request.GET.get('limit', 500) places = KircheOsm.objects\ .filter(mpoly__intersects=visible_map)[0:limit] # Create our json objects of places places_of_worship = [] for place in places: # Use the GeoDjango Point type to transform the cordinations in # other epsg formats if not place.point: continue try: place.point.transform(request.GET.get('epsg', 4326)) except Exception: return JSONResponse(message='Error by epsg transformation', _code=422) _place = { 'id': place.id, 'name': place.name, 'lon': place.point.x, 'lat': place.point.y, 'religion': place.religion, 'denomination': place.denomination, } places_of_worship.append(_place) return JSONResponse( request_id=request.GET.get('request_id'), places_of_worship=places_of_worship, places_of_worship_count=places.count() )
def __init__(self, options): super(Importer, self).__init__() self._images = {obj.url: obj for obj in Image.objects.all()} self.options = options self.verbosity = options['verbosity'] self.logger = logging.getLogger(__name__) importer_langs = set(self.supported_languages) configured_langs = set(l[0] for l in settings.LANGUAGES) # Intersection is all the languages possible for the importer to use. self.languages = {} for lang_code in importer_langs & configured_langs: # FIXME: get language name translations from Django lang_obj, _ = Language.objects.get_or_create(id=lang_code) self.languages[lang_code] = lang_obj self.target_srid = settings.PROJECTION_SRID gps_srs = SpatialReference(4326) target_srs = SpatialReference(self.target_srid) if getattr(settings, 'BOUNDING_BOX'): self.bounding_box = Polygon.from_bbox(settings.BOUNDING_BOX) self.bounding_box.set_srid(self.target_srid) target_to_gps_ct = CoordTransform(target_srs, gps_srs) self.bounding_box.transform(target_to_gps_ct) else: self.bounding_box = None self.gps_to_target_ct = CoordTransform(gps_srs, target_srs) self.setup()
def filter_bbox(self, queryset, bbox): """ modify the queryset q to limit to data that intersects with the provided bbox bbox - 4 tuple of floats representing 'southwest_lng,southwest_lat, northeast_lng,northeast_lat' returns the modified query """ bbox = [float(coord) for coord in bbox.split(',')] search_box = Polygon.from_bbox(bbox) for model in ModelDescription.objects.all(): django_model = model.get_django_model() sql = """SELECT "{layername}"."fid" FROM "{layername}" \ WHERE ST_Intersects("{layername}"."the_geom", ST_Transform(ST_GeomFromEWKT('srid=4326;{bbox_ewkt}'), \ {projection})) LIMIT 1;""".format( layername=model.name, bbox_ewkt=search_box.ewkt, projection=django_model.objects.first().the_geom.srid ) try: cursor.execute(sql) if not cursor.fetchone(): queryset = queryset.exclude(id=model.layer_id) except: pass return queryset
def setUp(self,): self.path = os.path.dirname(os.path.realpath(__file__)) parser = presets.PresetParser(self.path + '/files/hdm_presets.xml') self.tags = parser.parse() self.assertIsNotNone(self.tags) self.assertEquals(256, len(self.tags)) self.formats = ExportFormat.objects.all() #pre-loaded by 'insert_export_formats' migration Group.objects.create(name='DefaultExportExtentGroup') self.user = User.objects.create(username='******', email='*****@*****.**', password='******') bbox = Polygon.from_bbox((-7.96, 22.6, -8.14, 27.12)) the_geom = GEOSGeometry(bbox, srid=4326) self.job = Job.objects.create(name='TestJob', description='Test description', event='Nepal activation', user=self.user, the_geom=the_geom) self.uid = self.job.uid # add the formats to the job self.job.formats = self.formats self.job.save() for tag in self.tags: Tag.objects.create( key = tag['key'], value = tag['value'], job = self.job, data_model = 'osm', geom_types = tag['geom_types'] ) self.categories = self.job.categorised_tags
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 setUp(self,): Group.objects.create(name='TestDefaultExportExtentGroup') self.user1 = User.objects.create_user( username='******', email='*****@*****.**', password='******' ) self.user2 = User.objects.create_user( username='******', email='*****@*****.**', password='******' ) extents = (-3.9, 16.1, 7.0, 27.6) bbox = Polygon.from_bbox(extents) the_geom = GEOSGeometry(bbox, srid=4326) self.job1 = Job.objects.create(name='TestJob1', description='Test description', user=self.user1, the_geom=the_geom) self.job2 = Job.objects.create(name='TestJob2', description='Test description', user=self.user2, the_geom=the_geom) format = ExportFormat.objects.get(slug='obf') self.job1.formats.add(format) self.job2.formats.add(format) token = Token.objects.create(user=self.user1) self.client.credentials(HTTP_AUTHORIZATION='Token ' + token.key, HTTP_ACCEPT='application/json; version=1.0', HTTP_ACCEPT_LANGUAGE='en', HTTP_HOST='testserver')
def post(self, request): import json print(request.data, "in API") name = request.data["name"] geom = json.loads(request.data["geom"]) rpas = request.data["rpas"] start_day = request.data["start_day"] start_time = request.data["start_time"] end = request.data["end"] print(name, "name") print(geom, "geom") print(rpas, "rpas") print(start_day, "start_day") print(start_time, "start_time") print(end, "end") # start_day = "03/18/2020" # start_time = "10:30 AM" # end = "11:30 AM" from datetime import datetime date_object = datetime.strptime(start_day, "%m/%d/%Y") start_time_object = datetime.strptime(start_time, "%H:%M %p") end_time_object = datetime.strptime(end, "%H:%M %p") """ { "type":"FeatureCollection", "features":[ {"type":"Feature","properties":{}, "geometry":{"type":"Polygon", "coordinates":[ [ [36.901230812072754,-1.3365200875255174], [36.901230812072754,-1.3341603846017482], [36.903719902038574,-1.3341603846017482], [36.903719902038574,-1.3365200875255174], [36.901230812072754,-1.3365200875255174] ] ] }} ]} """ geom_type = geom["features"][0]["geometry"]["type"] coords = geom["features"][0]["geometry"]["coordinates"][0] print(coords, "coords") from django.contrib.gis.geos import ( GEOSGeometry, LineString, MultiLineString, Polygon, ) if geom_type == "Polygon": multi_line = Polygon(coords) print(multi_line, "multi_line") # line = LineString(coords) # print(line, "line") x = ReserveAirspace.objects.create( geom=multi_line, rpas_id=int(rpas), start_day=date_object, start_time=start_time_object, end=end_time_object, created_by=self.request.user, ) print(x, "x instance") return Response( {"ResultDesc": "Reserve Airspace Created successfully"}, content_type="application/json", status=status.HTTP_201_CREATED, )
from django.contrib.gis.geos import LineString, MultiPolygon, Point, Polygon from rest_framework.test import APITestCase from traffic_control.models import Lifecycle, MountType, Owner, TrafficControlDeviceType from users.models import User test_point = Point(10.0, 10.0, srid=settings.SRID) test_point_2 = Point(0.0, 0.0, srid=settings.SRID) test_point_3 = Point(100.0, 100.0, srid=settings.SRID) test_point_4 = Point(-44.3, 60.1, srid=4326) test_line = LineString((0.0, 0.0), (50.0, 0.0), srid=settings.SRID) test_line_2 = LineString((20.0, 20.0), (30.0, 30.0), srid=settings.SRID) test_line_3 = LineString((40.0, 40.0), (60.0, 60.0), srid=settings.SRID) test_line_4 = LineString((500.0, 500.0), (500.0, 550.0), srid=settings.SRID) test_polygon = Polygon( ((0.0, 0.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (0.0, 0.0)), srid=settings.SRID) test_polygon_2 = Polygon( ( (1000.0, 1000.0), (1000.0, 1050.0), (1050.0, 1050.0), (1050.0, 1000.0), (1000.0, 1000.0), ), srid=settings.SRID, ) test_polygon_3 = Polygon( ( (100.0, 100.0), (100.0, 150.0),
def setUp(self, ): self.path = os.path.dirname(os.path.realpath(__file__)) self.group = Group.objects.create(name='TestDefaultExportExtentGroup') profile = ExportProfile.objects.create(name='DefaultExportProfile', max_extent=2500000, group=self.group) self.user = User.objects.create_user(username='******', email='*****@*****.**', password='******') extents = (-3.9, 16.1, 7.0, 27.6) bbox = Polygon.from_bbox(extents) the_geom = GEOSGeometry(bbox, srid=4326) self.job = Job.objects.create(name='TestJob', event='Test Activation', description='Test description', user=self.user, the_geom=the_geom, export_formats=['obf']) token = Token.objects.create(user=self.user) self.client.credentials(HTTP_AUTHORIZATION='Token ' + token.key, HTTP_ACCEPT='application/json; version=1.0', HTTP_ACCEPT_LANGUAGE='en', HTTP_HOST='testserver') # create a test config f = File(open(self.path + '/files/hdm_presets.xml')) filename = f.name.split('/')[-1] name = 'Test Configuration File' self.config = ExportConfig.objects.create(name='Test Preset Config', filename=filename, upload=f, config_type='PRESET', user=self.user) f.close() self.assertIsNotNone(self.config) self.job.config = self.config self.job.save() self.tags = [{ "name": "Telecommunication office", "key": "office", "value": "telecommunication", "data_model": "HDM", "geom_types": ["point", "polygon"], "groups": [ 'HDM Presets v2.11', 'Commercial and Economic', 'Telecommunication' ] }, { "name": "Radio or TV Studio", "key": "amenity", "value": "studio", "data_model": "OSM", "geom_types": ["point", "polygon"], "groups": [ 'HDM Presets v2.11', 'Commercial and Economic', 'Telecommunication' ] }, { "name": "Telecommunication antenna", "key": "man_made", "value": "tower", "data_model": "OSM", "geom_types": ["point", "polygon"], "groups": [ 'HDM Presets v2.11', 'Commercial and Economic', 'Telecommunication' ] }, { "name": "Telecommunication company retail office", "key": "office", "value": "telecommunication", "data_model": "OSM", "geom_types": ["point", "polygon"], "groups": [ 'HDM Presets v2.11', 'Commercial and Economic', 'Telecommunication' ] }]
def get_resource_list(creator=None, group=None, user=None, owner=None, from_date=None, to_date=None, start=None, count=None, full_text_search=None, published=False, edit_permission=False, public=False, type=None, author=None, contributor=None, subject=None, coverage_type=None, north=None, south=None, east=None, west=None, include_obsolete=False): """ Return a list of pids for Resources that have been shared with a group identified by groupID. Parameters: queryType - string specifying the type of query being performed groupID - groupID of the group whose list of shared resources is to be returned Returns: A list of pids for resources that have been shared with the group identified by groupID. If no resources have been shared with a group, an empty list is returned. Return Type: resourceList Raises: Exceptions.NotAuthorized - The user is not authorized Exceptions.NotFound - The group identified by groupID does not exist Exception.ServiceFailure - The service is unable to process the request We may want to modify this method to return more than just the pids for resources so that some metadata for the list of resources returned could be displayed without having to call HydroShare.getScienceMetadata() and HydroShare.GetSystemMetadata() for every resource in the returned list. Implementation notes: For efficiency's sake, this returns a dictionary of query sets with one query set per defined resource type. At a high level someone could run through this whole list, collate the results, and send it back as a single list, but on the server side we don't do this because it gets too expensive quickly. parameters: group = Group or name user = User or name from_date = datetime object to_date = datetime object start = int count = int subject = list of subject type = list of resource type names, used for filtering coverage_type = geo parameter, one of box or point north = north coordinate west = west coordinate south = south coordinate east = east coordinate """ if not any((creator, group, user, owner, from_date, to_date, start, count, subject, full_text_search, public, type)): raise NotImplemented( "Returning the full resource list is not supported.") q = [] if type: query = Q(resource_type=type[0]) for t in type[1:]: query = query | Q(resource_type=t) q.append(query) if published: q.append(Q(doi__isnull=False)) if author: author_parties = ((Creator.objects.filter(email__in=author) | Creator.objects.filter(name__in=author))) q.append( Q(object_id__in=author_parties.values_list('object_id', flat=True))) if coverage_type in ('box', 'point'): if not north or not west or not south or not east: \ raise ValueError("coverage queries must have north, west, south, and east params") coverages = set() search_polygon = Polygon.from_bbox((east, south, west, north)) for coverage in Coverage.objects.filter(type="box"): coverage_polygon = Polygon.from_bbox( (coverage.value.get('eastlimit', None), coverage.value.get('southlimit', None), coverage.value.get('westlimit', None), coverage.value.get('northlimit', None))) if search_polygon.intersects(coverage_polygon): coverages.add(coverage.id) for coverage in Coverage.objects.filter(type="point"): coverage_shape = Point( coverage.value.get('east', None), coverage.value.get('north', None), ) if search_polygon.intersects(coverage_shape): coverages.add(coverage.id) coverage_hits = (Coverage.objects.filter(id__in=coverages)) q.append( Q(object_id__in=coverage_hits.values_list('object_id', flat=True))) if contributor: contributor_parties = ( (Contributor.objects.filter(email__in=contributor) | Contributor.objects.filter(name__in=contributor))) q.append( Q(object_id__in=contributor_parties.values_list('object_id', flat=True))) if edit_permission: if group: group = group_from_id(group) q.append(Q(gaccess__resource__in=group.gaccess.edit_resources)) q = _filter_resources_for_user_and_owner(user=user, owner=owner, is_editable=True, query=q) else: if creator: creator = user_from_id(creator) q.append(Q(creator=creator)) if group: group = group_from_id(group) q.append(Q(gaccess__resource__in=group.gaccess.view_resources)) q = _filter_resources_for_user_and_owner(user=user, owner=owner, is_editable=False, query=q) if from_date and to_date: q.append(Q(created__range=(from_date, to_date))) elif from_date: q.append(Q(created__gte=from_date)) elif to_date: q.append(Q(created__lte=to_date)) if subject: subjects = Subject.objects.filter(value__in=subject.split(',')) q.append(Q(object_id__in=subjects.values_list('object_id', flat=True))) flt = BaseResource.objects.all() if not include_obsolete: flt = flt.exclude(object_id__in=Relation.objects.filter( type='isReplacedBy').values('object_id')) for q in q: flt = flt.filter(q) if full_text_search: desc_ids = Description.objects.filter( abstract__icontains=full_text_search).values_list('object_id', flat=True) title_ids = Title.objects.filter( value__icontains=full_text_search).values_list('object_id', flat=True) # Full text search must match within the title or abstract if desc_ids: flt = flt.filter(object_id__in=desc_ids) elif title_ids: flt = flt.filter(object_id__in=title_ids) else: # No matches on title or abstract, so treat as no results of search flt = flt.none() qcnt = 0 if flt: qcnt = len(flt) if start is not None and count is not None: if qcnt > start: if qcnt >= start + count: flt = flt[start:start + count] else: flt = flt[start:qcnt] elif start is not None: if qcnt >= start: flt = flt[start:qcnt] elif count is not None: if qcnt > count: flt = flt[0:count] return flt
def get_admin_areas(run_timestamp, inputfile, country_code, KING_ID, printfn=printfn, get_only_king=False): ADMIN_LEVEL_MIN = 1 ADMIN_LEVEL_MAX = 8 KING = None admin_areas = [[] for i in range(12)] # index: admin_level, value admin_relations = {} # index: admin_level, value admin_relations_ways_ids = {} # this = self class RelsHandler(osmium.SimpleHandler): def relation(self, r): if 'boundary' in r.tags and r.tags[ 'boundary'] == 'administrative' and 'name' in r.tags and 'admin_level' in r.tags and ( not get_only_king or r.id == KING_ID): ways = [] for m in r.members: # outer (parts and exclaves) / inner (hole) if m.type == 'w' and m.role in ['outer']: ways.append(m.ref) admin_relations_ways_ids.setdefault(m.ref, []).append(r.id) try: admin_level = int(r.tags['admin_level']) except ValueError: return admin_relations[r.id] = { 'import_timestamp': run_timestamp, 'osm_id': r.id, 'osm_type': 'r', 'ways': ways, 'admin_level': admin_level, 'name': r.tags['name'], # .encode('utf-8').strip(), 'tags': {k: v for k, v in r.tags}, 'country_code': country_code, } # this.out2(f"REL {r.id} {r.tags['name'].encode('utf-8').strip()}") def make_valid(geom): cursor = connection._cursor() try: try: cursor.execute('SELECT ST_MakeValid(%s)', (PostGISAdapter(geom), )) row = cursor.fetchone() except: # Responsibility of callers to perform error handling. raise finally: # Close out the connection. See #9437. connection.close() return GEOSGeometry(row[0]) def maybe_make_valid(geom): if not geom.valid: return make_valid(geom) else: return geom class WaysHandler(osmium.SimpleHandler): def way(self, w): # ways that are admin areas if 'boundary' in w.tags and w.tags[ 'boundary'] == 'administrative' and 'name' in w.tags and 'admin_level' in w.tags: linestring = [] for node in w.nodes: linestring.append( [float(node.x) / 10000000, float(node.y) / 10000000]) if linestring[0][0] == linestring[-1][0] and linestring[0][ 1] == linestring[-1][1]: admin_level_aux = 0 try: admin_level_aux = int(w.tags['admin_level']) except Exception as e: print(f'wrong admin level: {w.tags["admin_level"]}') if admin_level_aux >= ADMIN_LEVEL_MIN and admin_level_aux <= ADMIN_LEVEL_MAX: poly = Polygon(linestring) admin_areas[admin_level_aux].append({ 'import_timestamp': run_timestamp, 'osm_id': w.id, 'osm_type': 'w', 'geometry': maybe_make_valid(poly), 'geometry_simple': maybe_make_valid(poly.simplify(0.001, True)), 'admin_level': admin_level_aux, 'name': w.tags['name'], # .encode('utf-8').strip(), 'tags': {k: v for k, v in w.tags}, 'country_code': country_code, }) # fill relations that are admin areas if w.id in admin_relations_ways_ids: linestring = [] for node in w.nodes: linestring.append( [float(node.x) / 10000000, float(node.y) / 10000000]) for rel_id in admin_relations_ways_ids[w.id]: if rel_id in admin_relations and 'ways' in admin_relations[ rel_id]: for i, wid in enumerate( admin_relations[rel_id]['ways']): if wid == w.id: admin_relations[rel_id]['ways'][i] = linestring printfn(f'Collecting rels, using {inputfile}') h = RelsHandler() h.apply_file(inputfile) printfn('Collecting ways & nodes') h = WaysHandler() h.apply_file(inputfile, locations=True) admin_count_ok = 0 admin_count_all = 0 admin_count = 0 printfn('Joining ways') for (k, v) in admin_relations.items(): admin_count_all = admin_count_all + 1 dbadminarea = AdministrativeArea.objects.filter(osm_id=v['osm_id'], osm_type=v['osm_type']) if dbadminarea: dbadminarea = dbadminarea[0] v['img_panorama'] = dbadminarea.img_panorama v['img_cuadrada'] = dbadminarea.img_cuadrada if v['admin_level'] >= ADMIN_LEVEL_MIN and v[ 'admin_level'] <= ADMIN_LEVEL_MAX: printfn(f"osmid={k} level={v['admin_level']} name={v['name']}", end="") wfull = [w for w in v['ways'] if not isinstance(w, int)] if len(wfull) == 0 or float(len(wfull)) / float(len( v['ways'])) < 0.8: printfn(f" NOK skipping adminarea, less than 80% of fragments") continue way, status = fix_polygon(wfull, 1000) if way is None: # si esta roto, buscar en la base de datos si hay uno con ese id y usar ese way printfn(f' ERROR: {status}') if dbadminarea: way = dbadminarea.geometry else: admin_count = admin_count + 1 printfn(f" OK -> {len(way)}") # last point equals first admin_count_ok = admin_count_ok + 1 try: poly = Polygon(way) v['geometry'] = maybe_make_valid(poly) v['geometry_simple'] = maybe_make_valid( poly.simplify(0.01, True)) if v['osm_id'] != KING_ID: admin_areas[v['admin_level']].append(v) except Exception as e: try: printfn(f" {e}, retrying as multipolygon") mp = [] for p in way: p_fixed, status = fix_polygon(p, 1000) if p_fixed: try: mp.append(Polygon(p_fixed + [p_fixed[0]])) except Exception as e3: printfn( f" {e3} {status}, skipping fragment. ({len(p_fixed)} nodes) [{status}]" ) poly = MultiPolygon(mp) v['geometry'] = maybe_make_valid(poly) v['geometry_simple'] = maybe_make_valid( poly.simplify(0.01, True)) if v['osm_id'] != KING_ID: admin_areas[v['admin_level']].append(v) printfn('-> ok') except Exception as e2: traceback.print_exc() printfn(f" {e2}, error") if v['osm_id'] == KING_ID: KING = v printfn( f"TOTALS: all({admin_count_all}) tried({admin_count}) ok({admin_count_ok}), really_ok({len(admin_areas)})" ) return admin_areas, KING
from .factories import HandelsregisterBuurtFactory from . import authorization log = logging.getLogger(__name__) def pretty_data(data): return json.dumps(data, indent=4, sort_keys=True) VIERKANTJE = MultiPolygon([ Polygon([ (52.3733600, 4.8920225), (52.3733600, 4.8930556), (52.3728228, 4.8930556), (52.3728228, 4.8920225), (52.3733600, 4.8920225), ], srid=4326) ]) BINNNEN_VIERKANTJE = Polygon([ (52.3733600, 4.8925225), (52.3733600, 4.8929556), (52.3729228, 4.8929556), (52.3729228, 4.8925225), (52.3733600, 4.8925225), ], srid=4326) VIERKANTJE_VERWEG = Polygon([
def is_in_allowed_bounding_boxes(self): for bbox in settings.GEOCODER_BOUNDING_BOXES: polygon = Polygon.from_bbox(bbox) if polygon.contains(self.centre): return True return False
def _load_polygon_data(self): bbox_wkt, bbox_z = bbox_data bbox_2d = GEOSGeometry(bbox_wkt, srid=32140) bbox_3d = Polygon(tuple((x, y, z) for (x, y), z in zip(bbox_2d[0].coords, bbox_z)), srid=32140) Polygon2D.objects.create(name='2D BBox', poly=bbox_2d) Polygon3D.objects.create(name='3D BBox', poly=bbox_3d)
def post(self, request): data = JSONDeserializer().deserialize(request.body) if data['id'] is None: mobile_survey = MobileSurvey() mobile_survey.createdby = self.request.user else: mobile_survey = MobileSurvey.objects.get(pk=data['id']) self.update_identities(data, mobile_survey, mobile_survey.users.all(), 'users', User, models.MobileSurveyXUser) self.update_identities(data, mobile_survey, mobile_survey.groups.all(), 'groups', Group, models.MobileSurveyXGroup) mobile_survey_card_ids = set([unicode(c.cardid) for c in mobile_survey.cards.all()]) form_card_ids = set(data['cards']) cards_to_remove = mobile_survey_card_ids - form_card_ids cards_to_add = form_card_ids - mobile_survey_card_ids cards_to_update = mobile_survey_card_ids & form_card_ids for card_id in cards_to_add: models.MobileSurveyXCard.objects.create(card=models.CardModel.objects.get(cardid=card_id), mobile_survey=mobile_survey, sortorder=data['cards'].index(card_id)) for card_id in cards_to_update: mobile_survey_card = models.MobileSurveyXCard.objects.filter(mobile_survey=mobile_survey).get(card=models.CardModel.objects.get(cardid=card_id)) mobile_survey_card.sortorder=data['cards'].index(card_id) mobile_survey_card.save() for card_id in cards_to_remove: models.MobileSurveyXCard.objects.filter(card=models.CardModel.objects.get(cardid=card_id), mobile_survey=mobile_survey).delete() if mobile_survey.active != data['active']: # notify users in the mobile_survey that the state of the mobile_survey has changed if data['active']: self.notify_mobile_survey_start(request, mobile_survey) else: self.notify_mobile_survey_end(request, mobile_survey) mobile_survey.name = data['name'] mobile_survey.description = data['description'] if data['startdate'] != '': mobile_survey.startdate = data['startdate'] if data['enddate'] != '': mobile_survey.enddate = data['enddate'] mobile_survey.datadownloadconfig = data['datadownloadconfig'] mobile_survey.active = data['active'] mobile_survey.tilecache = data['tilecache'] polygons = [] try: data['bounds'].upper() data['bounds'] = json.loads(data['bounds']) except AttributeError: pass if 'features' in data['bounds']: for feature in data['bounds']['features']: for coord in feature['geometry']['coordinates']: polygons.append(Polygon(coord)) mobile_survey.bounds = MultiPolygon(polygons) mobile_survey.lasteditedby = self.request.user try: connection_error = False with transaction.atomic(): mobile_survey.save() except Exception as e: if connection_error == False: error_title = _('Unable to save survey') error_message = e connection_error = JSONResponse({'success':False,'message': error_message,'title': error_title}, status=500) print connection_error return connection_error return JSONResponse({'success':True, 'mobile_survey': mobile_survey})
def setUp(self): ''' Create organisations and surfaces ''' self.secondary_category = ReportCategory.objects.all()[0] self.category = self.secondary_category.category_class self.region = OrganisationEntity(type=OrganisationEntity.REGION, name_nl="Region", name_fr="Region") self.region.save() self.region_group = OrganisationEntity( type=OrganisationEntity.DEPARTMENT, name_nl="Werken", name_fr="Travaux", phone="090987", dependency=self.region, email="*****@*****.**") self.region_group.save() self.region_group_mail_config = GroupMailConfig() self.region_group_mail_config.group = self.region_group self.region_group_mail_config.save() self.commune = OrganisationEntity( name_nl="Commune", name_fr="Commune", ) self.commune.save() self.commune_group = OrganisationEntity( type=OrganisationEntity.DEPARTMENT, name_nl="Werken", name_fr="Travaux", phone="090987", dependency=self.commune, email="*****@*****.**") self.commune_group.save() self.commune_group.dispatch_categories.add(self.secondary_category) self.commune_group_mail_config = GroupMailConfig() self.commune_group_mail_config.group = self.commune_group self.commune_group_mail_config.save() p1 = (148776, 171005) p2 = (150776, 171005) p3 = (150776, 169005) p4 = (148776, 169005) self.surface = OrganisationEntitySurface( geom=Polygon([p1, p2, p3, p4, p1]), owner=self.commune, ) self.surface.save() p1 = (149756, 169985) p2 = (149796, 169985) p3 = (149796, 170025) p4 = (149756, 170025) self.street_surface = StreetSurface( geom=Polygon([p1, p2, p3, p4, p1]), administrator=StreetSurface.REGION, ) self.street_surface.save()
def create_models(type=None, integration=False): users = [] obj_ids = [] with transaction.atomic(): map_data, user_data, people_data, dataset_data, document_data = create_fixtures( ) anonymous_group, created = Group.objects.get_or_create( name='anonymous') cont_group, created = Group.objects.get_or_create(name='contributors') perm = Permission.objects.get(codename='add_resourcebase') cont_group.permissions.add(perm) logger.debug("[SetUp] Get or create user admin") u, created = get_user_model().objects.get_or_create(username='******') u.set_password('admin') u.is_superuser = True u.first_name = 'admin' u.save() u.groups.add(anonymous_group) users.append(u) for ud, pd in zip(user_data, cycle(people_data)): user_name, password, first_name, last_name = ud logger.debug(f"[SetUp] Get or create user {user_name}") u, created = get_user_model().objects.get_or_create( username=user_name) u.set_password(password) u.first_name = first_name u.last_name = last_name u.save() u.groups.add(anonymous_group) if not (u.is_superuser or u.is_staff or u.is_anonymous): u.groups.add(cont_group) users.append(u) logger.debug(f"[SetUp] Add group {anonymous_group}") get_user_model().objects.get( username='******').groups.add(anonymous_group) from geonode.utils import DisableDjangoSignals with DisableDjangoSignals(skip=integration): if not type or ensure_string(type) == 'map': for md, user in zip(map_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = md logger.debug(f"[SetUp] Add map {title}") m = Map(title=title, abstract=abstract, zoom=4, projection='EPSG:4326', center_x=42, center_y=-73, owner=user, bbox_polygon=Polygon.from_bbox( (bbox_x0, bbox_y0, bbox_x1, bbox_y1)), ll_bbox_polygon=Polygon.from_bbox( (bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', category=category, metadata_only=title == 'map metadata true') m.save() m.set_default_permissions() m.clear_dirty_state() m.set_processing_state(enumerations.STATE_PROCESSED) obj_ids.append(m.id) for kw in kws: m.keywords.add(kw) m.save() if not type or ensure_string(type) == 'document': for dd, user in zip(document_data, cycle(users)): title, abstract, kws, (bbox_x0, bbox_x1, bbox_y0, bbox_y1), category = dd logger.debug(f"[SetUp] Add document {title}") m = Document(title=title, abstract=abstract, owner=user, bbox_polygon=Polygon.from_bbox( (bbox_x0, bbox_y0, bbox_x1, bbox_y1)), ll_bbox_polygon=Polygon.from_bbox( (bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', files=dfile, metadata_only=title == 'doc metadata true') m.save() m.set_default_permissions() m.clear_dirty_state() m.set_processing_state(enumerations.STATE_PROCESSED) obj_ids.append(m.id) for kw in kws: m.keywords.add(kw) m.save() if not type or ensure_string(type) == 'dataset': for ld, owner, subtype in zip(dataset_data, cycle(users), cycle(('raster', 'vector'))): title, abstract, name, alternate, ( bbox_x0, bbox_x1, bbox_y0, bbox_y1), start, kws, category = ld end = start + timedelta(days=365) logger.debug(f"[SetUp] Add dataset {title}") dataset = Dataset( title=title, abstract=abstract, name=name, alternate=alternate, bbox_polygon=Polygon.from_bbox( (bbox_x0, bbox_y0, bbox_x1, bbox_y1)), ll_bbox_polygon=Polygon.from_bbox( (bbox_x0, bbox_y0, bbox_x1, bbox_y1)), srid='EPSG:4326', uuid=str(uuid4()), owner=owner, temporal_extent_start=start, temporal_extent_end=end, date=start, subtype=subtype, category=category, metadata_only=title == 'dataset metadata true') dataset.save() dataset.set_default_permissions() dataset.clear_dirty_state() dataset.set_processing_state(enumerations.STATE_PROCESSED) obj_ids.append(dataset.id) for kw in kws: dataset.keywords.add(kw) dataset.save() return obj_ids
class DistrictFactory(factory.Factory): FACTORY_FOR = models.District name = factory.Sequence(lambda n: u"District name %s" % n) geom = factory.Sequence(lambda _: MultiPolygon( Polygon.from_bbox(geom_district_iter.next()), srid=settings.SRID))
def hybridQual(request, mapType): '''HYBRID qualified heatmap: accepts additional filter parameters AND uses NIncid thresh to select between heatmap vs marker display ''' nowDT = awareDT(datetime.now()) minDate = nowDT - timedelta(days=90) NIncidForMarkers = 75 userName = request.user.get_username() if mapType == 'general': qs0 = OakCrime.objects.filter(cdateTime__gt=minDate). \ filter(cdateTime__lt=nowDT). \ exclude(xlng__isnull=True). \ exclude(ylat__isnull=True). \ order_by('cdateTime') elif mapType == 'gun': # replicate query ala that for Scott Morris # select opd_rd, nvictim, nhospital, weapon, "gswP", "cdateTime", addr from "dailyIncid_oakcrime" # where "cdateTime" > '2017-01-01'::date and weapon like 'gun%' and (nvictim>0 or nhospital>0 or "gswP") # order by opd_rd qs0 = OakCrime.objects.filter(cdateTime__gt=minDate). \ filter(cdateTime__lt=nowDT). \ exclude(xlng__isnull=True). \ exclude(ylat__isnull=True). \ filter( models.Q(weapon__contains='gun') | models.Q(gswP=True) ) logline = 'username=%s hybridQual %s: qs0=%d' % (userName, mapType, qs0.count()) logger.info(logline) # list0 = list(qs0) # ocoFirst = list0[0] # ocoLast = list0[-1] # print('hybrid',ocoFirst.opd_rd,ocoFirst.cdateTime,ocoLast.opd_rd,ocoLast.cdateTime) ccatList = request.GET.getlist('crimeCat') logline = 'ccatList: %s' % (ccatList, ) logger.info(logline) NTopLevelCC = 15 # updated 200416 if len(ccatList) < NTopLevelCC: # NB: disjunction across separate crimeCat query sets! qscc = OakCrime.objects.none() for cc in ccatList: # NB: __startswith converts to LIKE cc% qs1 = qs0.filter(crimeCat__startswith=cc) qscc = (qscc | qs1) logline = 'ccatDBG: %s %d %d' % (cc, qs1.count(), qscc.count()) logger.info(logline) # print(cc,qs1.count(),qscc.count()) logline = 'username=%s hybridQual: crimeCat="%s" postCC=%d' % ( userName, ccatList, qscc.count()) logger.info(logline) elif mapType == 'gun': # for guns, restrict crimeCat to those mentioned ccMention = set() for oco in qs0: cc = oco.crimeCat ccbits = cc.split('_') ccMention.add(ccbits[0]) ccatList = list(ccMention) ccatList.remove('') qscc = OakCrime.objects.none() for cc in ccatList: # NB: __startswith converts to LIKE cc% qs1 = qs0.filter(crimeCat__startswith=cc) qscc = (qscc | qs1) # print(cc,qs1.count(),qscc.count()) logline = 'username=%s hybridQual: gun crimeCat="%s" postCC=%d' % ( userName, ccatList, qscc.count()) logger.info(logline) else: qscc = qs0 logline = 'username=%s hybridQual: No CC filter; postCC=%d' % ( userName, qscc.count()) logger.info(logline) # bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format mapboundStr = request.GET['mapBounds'] mapBound = eval(mapboundStr) # bbox = xmin, ymin, xmax, ymax poly = Polygon.from_bbox(mapBound) # HACK: better django might keep this manipulation over QuerySets? ocoList = list(qscc) # returned as Y,M,D STRING, to avoid JS/Python (0 vs 1-index) month numbering # JS display format = "MMM D YYYY" selectDateFmt = "%b %d %Y" dateDiffThresh = timedelta(days=2) minSelectDateStr = request.GET['minDate'] maxSelectDateStr = request.GET['maxDate'] minSelectDate = awareDT(datetime.strptime(minSelectDateStr, selectDateFmt)) maxSelectDate = awareDT(datetime.strptime(maxSelectDateStr, selectDateFmt)) # 2do: these queryset filters don't work? # NB: django comparison requires just date! # minSelectDate = datetime.date(minSelectDate) # maxSelectDate = datetime.date(maxSelectDate) # qs0 = qs0.filter(cdateTime__date__gt=minSelectDate) # qs0 = qs0.filter(cdateTime__date__lt=maxSelectDate) minDateChg = abs(minSelectDate - minDate) > dateDiffThresh if minDateChg: minDate = minSelectDate maxDateChg = abs(maxSelectDate - nowDT) > dateDiffThresh if maxDateChg: maxDate = maxSelectDate else: maxDate = nowDT ocoList3 = [] for oco in ocoList: dt = oco.cdateTime if (not minDateChg or (minDateChg and dt > minSelectDate)) and \ (not maxDateChg or (maxDateChg and dt < maxSelectDate)): ocoList3.append(oco) logline = 'username=%s hybridQual: postDateFilter=%d %s (%s) - %s (%s)' % \ (userName, len(ocoList3),minSelectDateStr,minDateChg, maxSelectDateStr, maxDateChg) logger.info(logline) ocoList4 = [] for oco in ocoList3: pt = oco.point if pt == None: logline = 'username=%s hybridQual: No point, DLog?! %s %s' % \ (userName, oco.opd_rd,oco.source) logger.info(logline) continue if poly.contains(pt): ocoList4.append(oco) incidList = ocoList4 nincid = len(incidList) elapTime = awareDT(datetime.now()) - nowDT logline = 'username=%s hybridQual: nincid=%d bbox=%s (%6.2f sec)' % ( userName, nincid, mapBound, elapTime.total_seconds()) logger.info(logline) context = {} context['mapType'] = mapType context['qualified'] = True context['nincid'] = nincid context['crimeCat'] = ccatList # NB: need to convert to list for javascript context['mapBounds'] = list(mapBound) # NB: javascript uses ZERO-based months! context['minDate'] = [minDate.year, minDate.month - 1, minDate.day] context['maxDate'] = [maxDate.year, maxDate.month - 1, maxDate.day] if minDateChg: context['minSlider'] = [ minSelectDate.year, minSelectDate.month - 1, minSelectDate.day ] else: context['minSlider'] = [minDate.year, minDate.month - 1, minDate.day] if maxDateChg: context['maxSlider'] = [ maxSelectDate.year, maxSelectDate.month - 1, maxSelectDate.day ] else: context['maxSlider'] = [nowDT.year, nowDT.month - 1, nowDT.day] # 2do: mapbox unifies heatmap with circles # dataArr = [ [lat, lng, intensity], ... ] # dataArr = [ [o.ylat,o.xlng,1] for o in ocoList4] # gjPoints = [ geojson.Point( (o.xlng, o.ylat) ) for o in ocoList4] # gjFeatures = [ geojson.Feature( geometry=gjpt, properties={"count": 1} ) for gjpt in gjPoints ] # 180130: extract only those incident details required for circle label; add as geojson properties # incid.opd_rd, incid.cdateTime, incid.crimeCat # also move major/minor crimeCat logic here (vs. javascript in heatmap.html) gjFeatures = [] for o in ocoList4: [jlat, jlng] = jitterCoord(o.ylat, o.xlng) # 180129: mapbox needs points as geojson, (lng,lat order) pt = geojson.Point((jlng, jlat)) f = geojson.Feature(geometry=pt, properties={"count": 1}) f.properties['opd_rd'] = o.opd_rd dtstr = o.cdateTime.strftime('%a,%b-%d-%y_%I:%M%p') f.properties['cdateTime'] = dtstr f.properties['crimeCat'] = o.crimeCat if mapType == 'gun': # if o.source.startswith("DLog"): if o.source.find('SOC_') == -1: f.properties['majorIncid'] = 'DLog' if o.gswP: f.properties['majorIncid'] = 'True' else: f.properties['majorIncid'] = ' False' else: majorP = majorCrimeCatP(o) f.properties['majorIncid'] = majorP gjFeatures.append(f) gjCollection = geojson.FeatureCollection(gjFeatures) rawgj = geojson.dumps(gjCollection) context['dataArr'] = rawgj return render(request, 'dailyIncid/heatmap.html', context)
def get_queryset(self): # Polygon parameters. lat_1 = self.request.query_params.get('lat_1', None) lat_2 = self.request.query_params.get('lat_2', None) lng_1 = self.request.query_params.get('lng_1', None) lng_2 = self.request.query_params.get('lng_2', None) # Parameter for exclude user. exclude_users_id = self.request.query_params.get( 'exclude_users_id', None) # Meeting Now meeting_now = self.request.query_params.get('meeting_now', None) # Filter by subject subject = self.request.query_params.get('subject', None) # Exclude teachers if (lat_1 and lat_2 and lng_1 and lng_2 and exclude_users_id is not None): ne = (lat_1, lng_1,) sw = (lat_2, lng_2,) xmin = sw[0] ymin = ne[1] xmax = sw[1] ymax = ne[0] bbox = (xmin, ymin, xmax, ymax) geom = Polygon.from_bbox(bbox) # Get all teachers excluding in list exclude_users_id # Filter when students want take a class at moment. if meeting_now is not None: queryset = LocationUser.objects.filter( user__is_teacher=True, user__is_active=True, user__settings__available=True ).exclude( user__pk__in=map(int, exclude_users_id.split(',')) ) else: queryset = LocationUser.objects.filter( user__is_teacher=True, user__is_active=True ).exclude( user__pk__in=map(int, exclude_users_id.split(',')) ) # Get all teachers in range location. queryset = queryset.filter( point__within=geom ) # Not exclude teachers if lat_1 and lat_2 and lng_1 and lng_2 and exclude_users_id is None: ne = (lat_1, lng_1,) sw = (lat_2, lng_2,) xmin = sw[0] ymin = ne[1] xmax = sw[1] ymax = ne[0] bbox = (xmin, ymin, xmax, ymax) geom = Polygon.from_bbox(bbox) # Get all teachers in location # Filter when students want take a class at moment. if meeting_now is not None: queryset = LocationUser.objects.filter( point__within=geom, user__is_teacher=True, user__is_active=True, user__settings__available=True ) else: queryset = LocationUser.objects.filter( point__within=geom, user__is_teacher=True, user__is_active=True ) # Filter teachers by subject if subject is not None and queryset: return queryset.filter( user__subject_teacher__subject__id=subject ) return queryset
def make_rectangle(bbox): """Given a bbox csv returns a geometry object for it""" xmin, ymin, xmax, ymax = (float(x) for x in bbox.split(',')) return Polygon(((xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin), (xmin, ymin)))
def save_building_footprint(absolute_vertices: list, height: float, name: str, root_tile: Tile): """Saves one building footprint to the database""" if not height: logger.warning( "Building with name {} does not have a valid height! Setting it to fallback" " of {}m".format(name, FALLBACK_HEIGHT)) operation = 'new' building = None # search for existing entry in db search_asset = Asset.objects.filter(name=name) if search_asset: asset_position = AssetPositions.objects.filter( asset=search_asset.first(), asset_type=AssetType.objects.get(name=ASSET_TYPE_NAME), tile_id=root_tile.id) if asset_position: asset_position = asset_position.first() building = BuildingFootprint.objects.filter(asset=asset_position) # check if the corresponding asset already has a building footprint assigned to it if building: building = building.first( ) # since name is unique the query set has to have size 1 operation = 'updated' # create new entry in non could be found if not building: # create a new building footprint building = BuildingFootprint() asset = Asset(name=name, asset_type=AssetType.objects.get(name=ASSET_TYPE_NAME)) asset.save() asset_position = AssetPositions( asset=asset, asset_type=AssetType.objects.get(name=ASSET_TYPE_NAME), tile_id=root_tile.id) # calculate the mean point # of the polygons vertices mean = [0, 0] for v in absolute_vertices: mean[0] += v[0] mean[1] += v[1] mean[0] /= len(absolute_vertices) mean[1] /= len(absolute_vertices) # calculate the relative positions of all vertices # towards the mean point and store them as Polygon relative_vertices = [] for v in absolute_vertices: relative_vertices.append((v[0] - mean[0], v[1] - mean[1])) relative_vertices = LinearRing(relative_vertices) relative_vertices = Polygon(relative_vertices) # set the values of asset_position and building and save them asset_position.location = Point(mean[0], mean[1]) building.vertices = relative_vertices building.height = height asset_position.orientation = 0 asset_position.save() building.asset = asset_position building.save() return operation
from .models import Provider, ServiceArea from .serializers import ServiceArea Serializer P1 = Polygon([ [2.109375, 15.29296875], [16.083984375, 16.34765625], [25.576171875, 0.87890625], [-3.69140625, -8.4375], [-13.623046875, 12.041015625], [-12.568359375, 15.1171875], [-11.25, 16.435546875], [-8.876953125, 16.611328125], [2.109375, 15.29296875] ]) P2 = Polygon([ [4.5703125, 13.623046875],
def test_proxy(self): "Testing Lazy-Geometry support (using the GeometryProxy)." # Testing on a Point pnt = Point(0, 0) nullcity = City(name='NullCity', point=pnt) nullcity.save() # Making sure TypeError is thrown when trying to set with an # incompatible type. for bad in [5, 2.0, LineString((0, 0), (1, 1))]: with self.assertRaisesMessage(TypeError, 'Cannot set'): nullcity.point = bad # Now setting with a compatible GEOS Geometry, saving, and ensuring # the save took, notice no SRID is explicitly set. new = Point(5, 23) nullcity.point = new # Ensuring that the SRID is automatically set to that of the # field after assignment, but before saving. self.assertEqual(4326, nullcity.point.srid) nullcity.save() # Ensuring the point was saved correctly after saving self.assertEqual(new, City.objects.get(name='NullCity').point) # Setting the X and Y of the Point nullcity.point.x = 23 nullcity.point.y = 5 # Checking assignments pre & post-save. self.assertNotEqual(Point(23, 5), City.objects.get(name='NullCity').point) nullcity.save() self.assertEqual(Point(23, 5), City.objects.get(name='NullCity').point) nullcity.delete() # Testing on a Polygon shell = LinearRing((0, 0), (0, 100), (100, 100), (100, 0), (0, 0)) inner = LinearRing((40, 40), (40, 60), (60, 60), (60, 40), (40, 40)) # Creating a State object using a built Polygon ply = Polygon(shell, inner) nullstate = State(name='NullState', poly=ply) self.assertEqual(4326, nullstate.poly.srid) # SRID auto-set from None nullstate.save() ns = State.objects.get(name='NullState') self.assertEqual(ply, ns.poly) # Testing the `ogr` and `srs` lazy-geometry properties. if gdal.HAS_GDAL: self.assertIsInstance(ns.poly.ogr, gdal.OGRGeometry) self.assertEqual(ns.poly.wkb, ns.poly.ogr.wkb) self.assertIsInstance(ns.poly.srs, gdal.SpatialReference) self.assertEqual('WGS 84', ns.poly.srs.name) # Changing the interior ring on the poly attribute. new_inner = LinearRing((30, 30), (30, 70), (70, 70), (70, 30), (30, 30)) ns.poly[1] = new_inner ply[1] = new_inner self.assertEqual(4326, ns.poly.srid) ns.save() self.assertEqual(ply, State.objects.get(name='NullState').poly) ns.delete()
def test_get_geodesic_area(self, ): bbox = GEOSGeometry(Polygon.from_bbox(self.extents), srid=4326) area = get_geodesic_area(bbox) self.assertEquals(2006874.9259034647, area / 1000000)
class DistrictFactory(factory.DjangoModelFactory): class Meta: model = models.District name = factory.Sequence(lambda n: u"District name %s" % n) geom = factory.Sequence(lambda _: MultiPolygon(Polygon.from_bbox(geom_district_iter.next()), srid=settings.SRID))
def test_geography_value(self): p = Polygon(((1, 1), (1, 2), (2, 2), (2, 1), (1, 1))) area = City.objects.annotate(a=functions.Area(Value(p, GeometryField(srid=4326, geography=True)))).first().a self.assertAlmostEqual(area.sq_km, 12305.1, 0)
def bbox_to_geom(s): try: return GEOSGeometry(Polygon.from_bbox(s.split(',')), srid=4326) except Exception: raise ValidationError({'bbox': 'Query bounding box is malformed.'})
def test_polygons(self): "Testing Polygon objects." prev = fromstr('POINT(0 0)') for p in self.geometries.polygons: # Creating the Polygon, testing its properties. poly = fromstr(p.wkt) self.assertEqual(poly.geom_type, 'Polygon') self.assertEqual(poly.geom_typeid, 3) self.assertEqual(poly.empty, False) self.assertEqual(poly.ring, False) self.assertEqual(p.n_i, poly.num_interior_rings) self.assertEqual(p.n_i + 1, len(poly)) # Testing __len__ self.assertEqual(p.n_p, poly.num_points) # Area & Centroid self.assertAlmostEqual(p.area, poly.area, 9) self.assertAlmostEqual(p.centroid[0], poly.centroid.tuple[0], 9) self.assertAlmostEqual(p.centroid[1], poly.centroid.tuple[1], 9) # Testing the geometry equivalence self.assertEqual(poly, fromstr(p.wkt)) # Should not be equal to previous geometry self.assertEqual(False, poly == prev) # Use assertEqual to test __eq__ self.assertNotEqual(poly, prev) # Use assertNotEqual to test __ne__ # Testing the exterior ring ring = poly.exterior_ring self.assertEqual(ring.geom_type, 'LinearRing') self.assertEqual(ring.geom_typeid, 2) if p.ext_ring_cs: self.assertEqual(p.ext_ring_cs, ring.tuple) self.assertEqual(p.ext_ring_cs, poly[0].tuple) # Testing __getitem__ # Testing __getitem__ and __setitem__ on invalid indices self.assertRaises(GEOSIndexError, poly.__getitem__, len(poly)) self.assertRaises(GEOSIndexError, poly.__setitem__, len(poly), False) self.assertRaises(GEOSIndexError, poly.__getitem__, -1 * len(poly) - 1) # Testing __iter__ for r in poly: self.assertEqual(r.geom_type, 'LinearRing') self.assertEqual(r.geom_typeid, 2) # Testing polygon construction. self.assertRaises(TypeError, Polygon, 0, [1, 2, 3]) self.assertRaises(TypeError, Polygon, 'foo') # Polygon(shell, (hole1, ... holeN)) rings = tuple(r for r in poly) self.assertEqual(poly, Polygon(rings[0], rings[1:])) # Polygon(shell_tuple, hole_tuple1, ... , hole_tupleN) ring_tuples = tuple(r.tuple for r in poly) self.assertEqual(poly, Polygon(*ring_tuples)) # Constructing with tuples of LinearRings. self.assertEqual(poly.wkt, Polygon(*tuple(r for r in poly)).wkt) self.assertEqual( poly.wkt, Polygon(*tuple(LinearRing(r.tuple) for r in poly)).wkt)
def handle(self, *args, **options): if len(args) != 1: raise Exception('Expected instance name as the first argument') name = args[0] if not options['user']: raise Exception('An admin user must be specified. with "--user"') if options.get('center', None) and options.get('geojson', None): raise Exception('You must specifiy only one of ' '"center" and "geojson"') elif (not options.get('center', None) and not options.get('geojson', None)): raise Exception('You must specifiy at least one of ' '"center" and "geojson"') if options['center']: center = options['center'].split(',') if len(center) != 2: raise Exception('Center should be a lon,lat pair') center_pt = Point(float(center[0]), float(center[1]), srid=4326) # Bounding box built in web mercator to have units in meters center_pt.transform(3857) x = center_pt.x y = center_pt.y offset = 50000 bounds = Polygon( ((x - offset, y - offset), (x - offset, y + offset), (x + offset, y + offset), (x + offset, y - offset), (x - offset, y - offset))) bounds = MultiPolygon((bounds, )) else: bounds = GEOSGeometry(open(options['geojson'], srid=4326).read()) if not options.get('url_name', None): raise Exception('You must specify a "url_name" starting with a ' 'lowercase letter and containing lowercase ' 'letters, numbers, and dashes ("-")') url_name = options.get('url_name') instance = Instance(config={}, name=name, bounds=bounds, is_public=True, url_name=url_name) instance.seed_with_dummy_default_role() instance.full_clean() instance.save() instance.boundaries = Boundary.objects.filter(geom__intersects=bounds) role = Role.objects.create( name='user', instance=instance, rep_thresh=0, default_permission=FieldPermission.WRITE_DIRECTLY) create_stewardship_udfs(instance) add_species_to_instance(instance) add_default_permissions(instance, roles=[role]) eco_benefits_conversion = \ BenefitCurrencyConversion.get_default_for_point(Point(x, y)) if eco_benefits_conversion: eco_benefits_conversion.save() instance.eco_benefits_conversion = eco_benefits_conversion instance.default_role = role instance.save() user = User.objects.get(username=options['user']) InstanceUser(instance=instance, user=user, role=role, admin=True).save_with_user(user)
def load_warning_data(cls): # sometimes error/empty objects = WeatherWarnings.requests_retry_session().get('https://idpgis.ncep.noaa.gov/arcgis/rest/services/NWS_Forecasts_Guidance_Warnings/watch_warn_adv/MapServer/1/query?' 'where=1=1&geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=esriSpatialRelIntersects&outFields=*&returnGeometry=false' '&returnTrueCurves=false&outSR=&returnIdsOnly=true&returnCountOnly=false&returnZ=false&returnM=false&returnDistinctValues=false&f=json', timeout=25) print objects.content object_ids = set(json.loads(objects.content)['objectIds']) url = 'https://idpgis.ncep.noaa.gov/arcgis/rest/services/NWS_Forecasts_Guidance_Warnings/watch_warn_adv/MapServer/1/{0}?f=json' for object in object_ids: try: obj = WeatherWarnings.requests_retry_session().get(url.format(object), timeout=15) obj = json.loads(obj.content) data = dict((k.lower(), v) for k, v in obj['feature']['attributes'].iteritems()) warninggeom = '' datapost = {} # Check if warning is already loaded and update as needed if WeatherWarnings.objects.filter(warnid=data['warnid']): datapost = WeatherWarnings.objects.filter(warnid=data['warnid']) warningfeature = datapost[0] if data['expiration'] != " ": warningfeature.expiration = date_parse(data['expiration']) if obj['feature'].get('geometry'): poly = map(LinearRing, obj['feature']['geometry']['rings']) warningfeature.warngeom = MultiPolygon(fromstr(str(Polygon(*poly).simplify(0.0001))),) warninggeom = MultiPolygon(fromstr(str(Polygon(*poly))),) warningfeature.issuance = date_parse(data['issuance']) warningfeature.idp_subset = data['idp_subset'] print data['warnid'] + " Updated" else: datapost['prod_type'] = data['prod_type'] datapost['idp_source'] = data['idp_source'] datapost['sig'] = data['sig'] datapost['wfo'] = data['wfo'] datapost['url'] = data['url'] datapost['phenom'] = data['phenom'] if data['expiration'] != " ": datapost['expiration'] = date_parse(data['issuance']) if obj['feature'].get('geometry'): poly = map(LinearRing, obj['feature']['geometry']['rings']) datapost['warngeom'] = MultiPolygon(fromstr(str(Polygon(*poly).simplify(0.0003))),) warninggeom = MultiPolygon(fromstr(str(Polygon(*poly))),) datapost['issuance'] = date_parse(data['issuance']) datapost['idp_subset'] = data['idp_subset'] datapost['warnid'] = data['warnid'] warningfeature = cls.objects.create(**datapost) print 'Created Warning: {0}'.format(data.get('warnid')) warningfeature.save() # Intersect with Departments and update table if overlap if(warninggeom != ''): intersectDepartmentList = FireDepartment.objects.filter(geom__intersects=warninggeom) if(intersectDepartmentList.count() > 0): WeatherWarnings.add_warnings_to_departments(intersectDepartmentList, warningfeature) print "Total intersecting Departments " + str(intersectDepartmentList.count()) except KeyError: print '{0} failed.'.format(object) print url.format(object) except IntegrityError: print '{0} failed.'.format(object) print url.format(object) print sys.exc_info() try: rollback() except: pass except: print '{0} failed.'.format(object) print url.format(object) print sys.exc_info() print '{0} Total Weather Warnings.'.format(WeatherWarnings.objects.all().count())
def import_file(self, filename, file): admin_json = geojson.loads(file.read()) # we keep track of all the osm ids we've seen because we remove all admin levels at this level # which weren't seen. (they have been removed) seen_osm_ids = set() osm_id = None # parse our filename.. they are in the format: # 192787admin2_simplified.json match = regex.match(r"(\w+\d+)admin(\d)(_simplified)?\.json$", filename, regex.V0) level = None is_simplified = None if match: level = int(match.group(2)) is_simplified = True if match.group(3) else False else: # else parse other filenames that are in # admin_level_0_simplified.json format. match = regex.match(r"admin_level_(\d)(_simplified)?\.json$", filename, regex.V0) if match: level = int(match.group(1)) is_simplified = True if match.group(2) else False else: self.stdout.write( self.style.WARNING( f"Skipping '{filename}', doesn't match file pattern.")) return None, set() # for each of our features for feature in admin_json["features"]: # what level are we? props = feature.properties # get parent id which is set in new file format parent_osm_id = props.get("parent_id") # if parent_osm_id is not set and not LEVEL_COUNTRY check for old file format if not parent_osm_id and level != AdminBoundary.LEVEL_COUNTRY: if level == AdminBoundary.LEVEL_STATE: parent_osm_id = props["is_in_country"] elif level == AdminBoundary.LEVEL_DISTRICT: parent_osm_id = props["is_in_state"] osm_id = props["osm_id"] name = props.get("name", "") if not name or name == "None" or level == AdminBoundary.LEVEL_COUNTRY: name = props.get("name_en", "") # try to find parent, bail if we can't parent = None if parent_osm_id and parent_osm_id != "None": parent = AdminBoundary.objects.filter( osm_id=parent_osm_id).first() if not parent: self.stdout.write( self.style.SUCCESS( f"Skipping {name} ({osm_id}) as parent {parent_osm_id} not found." )) continue # try to find existing admin level by osm_id boundary = AdminBoundary.objects.filter(osm_id=osm_id) # didn't find it? what about by name? if not boundary: boundary = AdminBoundary.objects.filter(parent=parent, name__iexact=name) # skip over items with no geometry if not feature["geometry"] or not feature["geometry"][ "coordinates"]: continue # pragma: can't cover polygons = [] if feature["geometry"]["type"] == "Polygon": polygons.append(Polygon(*feature["geometry"]["coordinates"])) elif feature["geometry"]["type"] == "MultiPolygon": for polygon in feature["geometry"]["coordinates"]: polygons.append(Polygon(*polygon)) else: raise Exception( "Error importing %s, unknown geometry type '%s'" % (name, feature["geometry"]["type"])) geometry = MultiPolygon(polygons) kwargs = dict(osm_id=osm_id, name=name, level=level, parent=parent) if is_simplified: kwargs["simplified_geometry"] = geometry else: kwargs["geometry"] = geometry # if this is an update, just update with those fields if boundary: if not parent: kwargs["path"] = name else: kwargs[ "path"] = parent.path + AdminBoundary.PADDED_PATH_SEPARATOR + name self.stdout.write( self.style.SUCCESS(f" ** updating {name} ({osm_id})")) boundary = boundary.first() boundary.update(**kwargs) # update any children boundary.update_path() # otherwise, this is new, so create it else: self.stdout.write( self.style.SUCCESS(f" ** adding {name} ({osm_id})")) AdminBoundary.create(**kwargs) # keep track of this osm_id seen_osm_ids.add(osm_id) # now remove any unseen boundaries if osm_id: last_boundary = AdminBoundary.objects.filter(osm_id=osm_id).first() if last_boundary: self.stdout.write( self.style.SUCCESS( f" ** removing unseen boundaries ({osm_id})")) country = last_boundary.get_root() unseen_boundaries = country.get_descendants().filter( level=level).exclude(osm_id__in=seen_osm_ids) deleted_count = 0 for unseen_boundary in unseen_boundaries: unseen_boundary.release() deleted_count += 1 if deleted_count > 0: self.stdout.write( f" ** Unseen boundaries removed: {deleted_count}") return country, seen_osm_ids else: return None, set() else: return None, set()
def get(self, request, left, bottom, right, top): poly = Polygon(((left, bottom), (left, top), (right, top), (right, bottom), (left, bottom))) nodes = Node.objects.filter(geom__within=poly) xml = serialize_map(poly, nodes)
def sample_query(user, params, qs): if isinstance(user, AnonymousUser): qs = qs.filter(public_data=True) else: qs = qs.filter(Q(owner=user) | Q(public_data=True)) if params.get('ids'): qs = qs.filter(pk__in=params['ids'].split(',')) if params.get('collectors'): qs = qs.filter(collector_name__in=params['collectors'].split(',')) if params.get('numbers'): qs = qs.filter(number__in=params['numbers'].split(',')) if params.get('countries'): qs = qs.filter(country__in=params['countries'].split(',')) if params.get('location_bbox'): bbox = Polygon.from_bbox(params['location_bbox'].split(',')) qs = qs.filter(location_coords__contained=bbox) if params.get('polygon_coords'): try: polygon = Polygon((json.loads(params['polygon_coords']))) except GEOSException: raise ValueError("Invalid polygon coordinates. Please check if " "the points form a closed linestring or not.") qs = qs.filter(location_coords__contained=polygon) if params.get('metamorphic_grades'): metamorphic_grades = params['metamorphic_grades'].split(',') qs = qs.filter(metamorphic_grades__name__in=metamorphic_grades) if params.get('metamorphic_regions'): metamorphic_regions = params['metamorphic_regions'].split(',') qs = qs.filter(metamorphic_regions__name__in=metamorphic_regions) if params.get('minerals'): minerals = params['minerals'].split(',') if params.get('minerals_and') == 'True': for mineral in minerals: qs = qs.extra(where=[ """ EXISTS ( SELECT 0 FROM sample_minerals sm INNER JOIN minerals m ON sm.mineral_id = m.id WHERE samples.id = sm.sample_id AND m.name = %s ) """ ], params=[mineral]) else: qs = qs.filter(minerals__name__in=minerals) if params.get('owners'): qs = qs.filter(owner__name__in=params['owners'].split(',')) if params.get('emails'): qs = qs.filter(owner__email__in=params['emails'].split(',')) if params.get('references'): qs = qs.filter(references__name__in=params['references'].split(',')) if params.get('regions'): qs = qs.filter(regions__overlap=params['regions'].split(',')) if params.get('rock_types'): qs = qs.filter(rock_type__name__in=params['rock_types'].split(',')) if params.get('start_date'): qs = qs.filter(collection_date__gt=params['start_date']) if params.get('end_date'): qs = qs.filter(collection_date__lt=params['end_date']) if params.get('sesar_number'): qs = qs.filter(sesar_number__in=params['sesar_number'].split(',')) return qs
def collect_eo_metadata(qs, insert=None, exclude=None, bbox=False): """ Helper function to collect EO metadata from all EOObjects in a queryset, plus additionals from a list and exclude others from a different list. If bbox is ``True`` then the returned polygon will only be a minimal bounding box of the collected footprints. :param qs: the :class:`django.db.QuerySet` to collect all EO metadata from :param insert: an iterable of all objects that are to be inserted (thus not entailed in the queryset) and should be considered when collection metadata :param exclude: an iterable of objects that are considered to be excluded from the list and should not be used for metadata collection :param bbox: if this is set to ``True`` the footprint will only be represented as a minimal BBOX polygon of all collected footprints. This is preferable for large collections. """ values = qs.exclude(pk__in=[eo_object.pk for eo_object in exclude or ()]).aggregate( begin_time=Min("begin_time"), end_time=Max("end_time"), footprint=Union("footprint")) begin_time, end_time, footprint = (values["begin_time"], values["end_time"], values["footprint"]) # workaround for Django 1.4 bug: aggregate times are strings if isinstance(begin_time, string_types): begin_time = parse_datetime(begin_time) if isinstance(end_time, string_types): end_time = parse_datetime(end_time) if begin_time and is_naive(begin_time): begin_time = make_aware(begin_time, get_current_timezone()) if end_time and is_naive(end_time): end_time = make_aware(end_time, get_current_timezone()) for eo_object in insert or (): if begin_time is None: begin_time = eo_object.begin_time elif eo_object.begin_time is not None: begin_time = min(begin_time, eo_object.begin_time) if end_time is None: end_time = eo_object.end_time elif eo_object.end_time is not None: end_time = max(end_time, eo_object.end_time) if footprint is None: footprint = eo_object.footprint elif eo_object.footprint is not None: footprint = footprint.union(eo_object.footprint) if not isinstance(footprint, MultiPolygon) and footprint is not None: footprint = MultiPolygon(footprint) if bbox and footprint is not None: footprint = MultiPolygon(Polygon.from_bbox(footprint.extent)) return begin_time, end_time, footprint
def import_file(self, filename, file): admin_json = geojson.loads(file.read()) # we keep track of all the osm ids we've seen because we remove all admin levels at this level # which weren't seen. (they have been removed) seen_osm_ids = [] # parse our filename.. they are in the format: 192787admin2_simplified.json match = re.match(r'(\w\d+)admin(\d)(_simplified)?\.json$', filename) if not match: print "Skipping '%s', doesn't match file pattern." % filename country_osm_id = match.group(1) level = int(match.group(2)) is_simplified = True if match.group(3) else False # for each of our features for feature in admin_json['features']: # what level are we? props = feature.properties parent_osm_id = None if level == STATE_LEVEL: parent_osm_id = props['is_in_country'] elif level == DISTRICT_LEVEL: parent_osm_id = props['is_in_state'] osm_id = props['osm_id'] name = props.get('name_en', '') if not name or name == 'None': name = props['name'] # try to find parent, bail if we can't parent = None if parent_osm_id and parent_osm_id != 'None': parent = AdminBoundary.objects.filter(osm_id=parent_osm_id).first() if not parent: print("Skipping %s (%s) as parent %s not found." % (name, osm_id, parent_osm_id)) continue # try to find existing admin level by osm_id boundary = AdminBoundary.objects.filter(osm_id=osm_id) # didn't find it? what about by name? if not boundary: boundary = AdminBoundary.objects.filter(parent=parent, name__iexact=name) # skip over items with no geometry if not feature['geometry'] or not feature['geometry']['coordinates']: continue polygons = [] if feature['geometry']['type'] == 'Polygon': polygons.append(Polygon(*feature['geometry']['coordinates'])) elif feature['geometry']['type'] == 'MultiPolygon': for polygon in feature['geometry']['coordinates']: polygons.append(Polygon(*polygon)) else: raise Exception("Error importing %s, unknown geometry type '%s'" % (name, feature['geometry']['type'])) geometry = MultiPolygon(polygons) kwargs = dict(osm_id=osm_id, name=name, level=level, parent=parent) if is_simplified: kwargs['simplified_geometry'] = geometry else: kwargs['geometry'] = geometry # if this is an update, just update with those fields if boundary: print " ** updating %s (%s)" % (name, osm_id) boundary.update(**kwargs) # otherwise, this is new, so create it else: print " ** adding %s (%s)" % (name, osm_id) AdminBoundary.objects.create(**kwargs) # keep track of this osm_id seen_osm_ids.append(osm_id) # now remove any unseen boundaries # TODO: how do we deal with values already assigned to a location? we should probably retry to do some # matching based on the new names? (though unlikely to match if the name didn't match when trying to find the boundary) if level == STATE_LEVEL: AdminBoundary.objects.filter(level=level, parent__osm_id=country_osm_id).exclude(osm_id__in=seen_osm_ids).delete() elif level == DISTRICT_LEVEL: AdminBoundary.objects.filter(level=level, parent__parent__osm_id=country_osm_id).exclude(osm_id__in=seen_osm_ids).delete()