def insert_record(conn, id, geojson): poly = shape(geojson['geometry']) # Buffer by 5 miles - if you are within 5 miles of a lake you should # still hear about the lake monster! buffered_poly = buffer_polygon_in_meters(poly, 5 * 1600) if poly.geom_type == "Polygon": poly = MultiPolygon([poly]) if buffered_poly.geom_type == "Polygon": buffered_poly = MultiPolygon([buffered_poly]) conn.execute( """ INSERT INTO cryptids ( id, name, wikipedia_url, additional_url, description, copyright, first_sighted, last_sighted, geom, range) VALUES(?, ?, ?, ?, ?, ?, ?, ?, GeomFromText(?, 4326), GeomFromText(?, 4326)) """, ( id, geojson["properties"]["name"], geojson["properties"].get("wikipedia_url"), geojson["properties"].get("additional_url"), geojson["properties"]["description"], geojson["properties"].get("copyright"), geojson["properties"].get("first_sighted") or "", geojson["properties"].get("last_sighted") or "", buffered_poly.wkt, poly.wkt, ))
def unwrap(self, geom): '''geom : shapely.geometry''' if type(geom) in [MultiPoint, Point]: return (self.unwrap_point(geom)) assert (type(geom) in [Polygon, MultiPolygon]) return_type = type(geom) ## return the geometry iterator it = self._get_iter_(geom) ## loop through the polygons determining if any coordinates need to be ## shifted and flag accordingly. adjust = False for polygon in it: coords = np.array(polygon.exterior.coords) if np.any(coords[:, 0] < self.axis): adjust = True break ## wrap the polygon if requested if adjust: ## intersection with the two regions left = geom.intersection(self.clip1) right = geom.intersection(self.clip2) ## pull out the right side polygons right_polygons = [poly for poly in self._get_iter_(right)] ## adjust polygons falling the left window if isinstance(left, Polygon): left_polygons = [self._unwrap_shift_(left)] else: left_polygons = [] for polygon in left: left_polygons.append(self._unwrap_shift_(polygon)) ## merge polygons into single unit try: ret = MultiPolygon(left_polygons + right_polygons) except TypeError: left = filter(lambda x: type(x) != LineString, left_polygons) right = filter(lambda x: type(x) != LineString, right_polygons) ret = MultiPolygon(left + right) ## if polygon does not need adjustment, just return it. else: ret = geom ## ensure the return types did not change if return_type != type(ret): if return_type == Polygon and type(ret) == MultiPolygon: ret = ret[0] else: raise (NotImplementedError) return (ret)
def _load_US_boundary(self): """ Loads a GeoJSON multipolygon created separately by merging the polygons provided here: https://developers.google.com/kml/documentation/us_states.kml """ geojson_multipolygon_file = open("united_states_border.json", "r") geojson_multipolygon = json.loads(geojson_multipolygon_file.read()) geojson_multipolygon_file.close() # create a shapely multipolygon - this will be used to determine if a generated grid cell lies within the USA self._US_boundary = MultiPolygon(geojson_multipolygon["coordinates"], context_type="geojson")
def getRegions(point, regiondf): res = 0 for index, row in regiondf.iterrows(): print(row['geometry']) p = MultiPolygon(row['geometry']) print(p) if p.contains(point): res = row["name"] break print(res) return res
def _conv_to_multi_(geom): '''Geometry conversion to single type.''' if isinstance(geom,Point): pass else: try: geom = MultiPolygon(geom) except TypeError: geom = MultiPolygon([geom]) except AssertionError: geom = wkb.loads(geom.wkb) return(geom)
def extractPolygons(geom): if isinstance(geom,Polygon) or isinstance(geom,MultiPolygon): return geom elif isinstance(geom,GeometryCollection): result = None for g in geom: p = extractPolygons(g) if not p: continue elif not result: result = p elif isinstance(result,MultiPolygon): result = [geom1 for geom1 in result.geoms] if isinstance(p,Polygon): result.append(p) result = MultiPolygon(result) else: for geom1 in p.geoms: result.append(geom1) result = MultiPolygon(result) else: if isinstance(p,Polygon): result = MultiPolygon([result,p]) else: result = [result] for geom1 in p.geoms: result.append(geom1) result = MultiPolygon(result) return result else: return None
def PointsToMultiPointGeom(self, ptL): from shapely.geometry import Point, MultiPoint ptgeomL = [] for pt in ptL: ptgeomL.append(Point(pt)) self.shapelyGeom = MultiPoint(ptgeomL) self.ShapelyToOgrGeom()
def get_as_shapely(self, cell, layer=None, datatype=None): """ Returns a shapely object imported from the GDSII-file. :param cell: Name of the cell or a cell :param layer: Layer which should be imported, ´None´ means all layers :param datatype: Datatype which should be imported, ´None´ means all datatypes :return: A shapely object """ geometry = [] gdspy_cell = self.gdslib.cells[cell] if isinstance(cell, str) else cell for polygon in gdspy_cell.polygons: if self.layer is not None and layer != polygon.layers[0]: continue if self.datatype is not None and datatype != polygon.datatypes[0]: continue geometry.append(Polygon(polygon.polygons[0]).buffer(0)) # .buffer(0) for healing geometries for reference in gdspy_cell.references: sub_geometry = self.get_as_shapely(reference.ref_cell, layer, datatype) if sub_geometry.is_empty: continue sub_geometry = scale(sub_geometry, *[reference.magnification] * 2) if reference.magnification else sub_geometry sub_geometry = scale(sub_geometry, -1) if reference.x_reflection else sub_geometry sub_geometry = rotate(sub_geometry, reference.rotation, origin=(0, 0)) if reference.rotation else sub_geometry sub_geometry = translate(sub_geometry, *reference.origin) geometry.extend(sub_geometry) return MultiPolygon(geometry)
def get_iter(self): headers = self.get_headers() vid = 1 cid = 1 ugid = self.ugid for alias, calc in self.calc.iteritems(): ds = self.variables[alias] did = ds.request_dataset.did variable = ds.request_dataset.variable for calc_name, calc_value in calc.iteritems(): for geom, attrs in ds.get_iter_value(value=calc_value, temporal_group=True): attrs['did'] = did attrs['variable'] = variable attrs['alias'] = alias attrs['calc_name'] = calc_name attrs['vid'] = vid attrs['cid'] = cid attrs['ugid'] = ugid row = [attrs[key] for key in headers] if type(geom) == Polygon: geom = MultiPolygon([geom]) yield (geom, row) cid += 1 vid += 1
def split(self, is_recursing=False): geometry = self.geometry if is_recursing: assert isinstance(geometry, Polygon) ret = [] for interior in self.iter_interiors(): split_polygon = self.create_split_polygons(interior) for sp in split_polygon: ret.append(geometry.intersection(sp)) else: if isinstance(geometry, MultiPolygon): itr = geometry else: itr = [geometry] ret = [] for geometry_part in itr: try: geometry_part_splitter = self.__class__(geometry_part) except NoInteriorsError: ret.append(geometry_part) else: split = geometry_part_splitter.split(is_recursing=True) for element in split: ret.append(element) return MultiPolygon(ret)
def import_shapefile_to_db(filepath): connection = psycopg2.connect(host=DB_HOSTNAME, database="census_uk", user="******", password="******") cursor = connection.cursor(cursor_factory=psycopg2.extras.DictCursor) count = 0 shp = fiona.open(filepath) nb_tracts = len(shp) for feature in shp: type = feature['type'] id = feature['id'] geom = shape(feature['geometry']) if geom.geom_type == "Polygon": geom = MultiPolygon([geom]) prop = feature['properties'] geo_code = prop['geo_code'] label = prop['label'] query_string = """INSERT INTO tracts (geo_code, geom) VALUES (%s, ST_GeomFromText(%s, %s)) ON CONFLICT DO NOTHING;""" data = (geo_code, geom.wkt, EPSG) cursor.execute(query_string, data) count += 1 if count % 100 == 0: utils.print_progress("Done: %.2f" % (100.0 * count / nb_tracts)) # if count == 10: # break connection.commit()
def _get_iter_(self): ## we want to break out the date parts if any date parts are present ## in the headers argument. headers = self.get_headers() intersection = set(headers).intersection(set(['year', 'month', 'day'])) if len(intersection) > 0: add_date_parts = True else: add_date_parts = False vid = 1 ugid = self.ugid for alias, ds in self.variables.iteritems(): did = ds.request_dataset.did variable = ds.request_dataset.variable for geom, attrs in ds.get_iter_value(): attrs['did'] = did attrs['alias'] = alias attrs['variable'] = variable attrs['vid'] = vid attrs['ugid'] = ugid if add_date_parts: attrs['year'] = attrs['time'].year attrs['month'] = attrs['time'].month attrs['day'] = attrs['time'].day if type(geom) == Polygon: geom = MultiPolygon([geom]) yield (geom, attrs) vid += 1
def get_converter_iterator(self,geom_dict): for dct in geom_dict: dct_copy = dct.copy() geom = dct_copy.pop('geom') if isinstance(geom,Polygon): geom = MultiPolygon([geom]) yield(dct_copy,geom)
def create_dummy_extract(): date = datetime.datetime.now() real_estate = RealEstateRecord( u'test', u'BL', u'Laufen', 2770, 1000, MultiPolygon(), ViewServiceRecord('test_link', 1, 1.0, {'de': 'test_legend'})) plr_office = OfficeRecord({u'en': u'PLR Authority'}) resolver = DottedNameResolver() date_method_string = Config.get('extract').get('base_data').get( 'methods').get('date') date_method = resolver.resolve(date_method_string) av_update_date = date_method(real_estate) base_data = Config.get_base_data(av_update_date) av_provider_method_string = Config.get('extract').get('base_data').get( 'methods').get('provider') av_provider_method = resolver.resolve(av_provider_method_string) cadaster_state = date theme = ThemeRecord(u'TEST', {u'de': u'TEST TEXT'}) datasources = [DatasourceRecord(theme, date, plr_office)] plr_cadastre_authority = Config.get_plr_cadastre_authority() embeddable = EmbeddableRecord(cadaster_state, plr_cadastre_authority, av_provider_method(real_estate), av_update_date, datasources) record = ExtractRecord(real_estate, ImageRecord('100'.encode('utf-8')), ImageRecord('100'.encode('utf-8')), ImageRecord('100'.encode('utf-8')), ImageRecord('100'.encode('utf-8')), plr_office, base_data, embeddable) return record
def prepare_geometry_variable(self, subset_geom, rhs_tol=10.0, inplace=True): """ Prepared a geometry variable for subsetting. This method: * Appropriately wraps subset geometries for spherical coordinate systems. :param subset_geom: The geometry variable to prepare. :type subset_geom: :class:`~ocgis.GeometryVariable` :param float rhs_tol: The amount, in matching coordinate system units, to buffer the right hand selection geometry. :param bool inplace: If ``True``, modify the object in-place. """ # TODO: This should work with arbitrary geometries not just bounding boxes. assert subset_geom.size == 1 if self.is_wrappable and subset_geom.is_bbox and subset_geom.wrapped_state == WrappedState.UNWRAPPED: if not inplace: subset_geom = subset_geom.deepcopy() svalue = subset_geom.get_value() buffered_bbox = svalue[0].bounds if buffered_bbox[0] < 0.: bbox_rhs = list(deepcopy(buffered_bbox)) bbox_rhs[0] = buffered_bbox[0] + 360. bbox_rhs[2] = 360. + rhs_tol bboxes = [buffered_bbox, bbox_rhs] else: bboxes = [buffered_bbox] bboxes = [box(*b) for b in bboxes] if len(bboxes) > 1: svalue[0] = MultiPolygon(bboxes) return subset_geom
def test_split(self): to_test = [ self.fixture_polygon_with_hole, MultiPolygon( [self.fixture_polygon_with_hole, box(200, 100, 300, 400)]) ] desired_counts = {0: 4, 1: 5} for ctr, t in enumerate(to_test): ge = GeometrySplitter(t) split = ge.split() self.assertEqual(len(split), desired_counts[ctr]) self.assertEqual(split.area, t.area) actual_bounds = [g.bounds for g in split] actual_areas = [g.area for g in split] desired_bounds = [(2.0, 10.0, 3.0, 13.0), (3.0, 10.0, 4.0, 13.0), (3.0, 13.0, 4.0, 20.0), (2.0, 13.0, 3.0, 20.0)] desired_areas = [1.75, 1.75, 5.75, 5.75] if ctr == 1: desired_bounds.append((200.0, 100.0, 300.0, 400.0)) desired_areas.append(30000.0) self.assertEqual(actual_bounds, desired_bounds) self.assertEqual(actual_areas, desired_areas)
def get_as_shapely(self, cell, layer=None, datatype=None): geometry = [] gdspy_cell = self.gdslib.cells[cell] if isinstance(cell, str) else cell for polygon in gdspy_cell.polygons: if self.layer is not None and layer != polygon.layers[0]: continue if self.datatype is not None and datatype != polygon.datatypes[0]: continue geometry.append(Polygon(polygon.polygons[0]).buffer( 0)) # .buffer(0) for healing geometries for reference in gdspy_cell.references: sub_geometry = self.get_as_shapely(reference.ref_cell, layer, datatype) if sub_geometry.is_empty: continue sub_geometry = scale( sub_geometry, *[reference.magnification] * 2) if reference.magnification else sub_geometry sub_geometry = scale( sub_geometry, -1) if reference.x_reflection else sub_geometry sub_geometry = rotate( sub_geometry, reference.rotation, origin=(0, 0)) if reference.rotation else sub_geometry sub_geometry = translate(sub_geometry, *reference.origin) geometry.extend(sub_geometry) return MultiPolygon(geometry)
def test_dumps_polygon(self): for d in ['2d', '3d']: poly1 = wkt.loads(self.fixture_wkt[d]['polygon']) poly2 = wkt.loads(self.fixture_wkt[d]['polygon_hole']) geoms = [ orient(poly1, sign=-1.0), poly2, MultiPolygon([poly1, poly2]) ] res = cf.dumps('polygon', geoms) # res.describe() self.assertEqual(res.outer_ring_order, OuterRingOrder.CCW) self.assertEqual(res.closure_convention, ClosureConvention.CLOSED) self.assertIsInstance(res, CFGeometryCollection) for ctr, c in enumerate(res.cindex): loaded = cf.loads('polygon', c, res.x, res.y, z=res.z, multipart_break=res.multipart_break, hole_break=res.hole_break) if ctr == 0: desired = orient(geoms[0]) else: desired = geoms[ctr] self.assertTrue(loaded.almost_equals(desired))
def make_valid_pyclipper(shape): """ Use the pyclipper library to "union" a polygon on its own. This operation uses the even-odd rule to determine which points are in the interior of the polygon, and can reconstruct the orientation of the polygon from that. The pyclipper library is robust, and uses integer coordinates, so should not produce any additional degeneracies. Before cleaning the polygon, we remove all degenerate inners. This is useful to remove inners which have collapsed to points or lines, which can interfere with the cleaning process. """ # drop all degenerate inners clean_shape = _drop_degenerate_inners(shape) pc = pyclipper.Pyclipper() try: pc.AddPaths(_coords(clean_shape), pyclipper.PT_SUBJECT, True) # note: Execute2 returns the polygon tree, not the list of paths result = pc.Execute2(pyclipper.CT_UNION, pyclipper.PFT_EVENODD) except pyclipper.ClipperException: return MultiPolygon([]) return _polytree_to_shapely(result)
def vec_for(): def vec_write(vecvec): print({ 'properties': { 'bin_left': bin_left, 'bin_right': bin_right } }) vecvec.write({ 'geometry': multipolygon, 'properties': { 'bin_left': bin_left, 'bin_right': bin_right } }) for i,pixel_value in uniq_val_subset.iterrows(): polygons = [shape(geom) for geom,value in shapes if value==pixel_value[0]] multipolygon = mapping(MultiPolygon(polygons)) bin_left = bins[i-di] bin_right = bins[i] if args.shapefile: vec_write(vec['ESRI Shapefile']) if args.geojson: vec_write(vec['GeoJSON'])
def PointsToPolygonGeom(self, ptL): from shapely.geometry import Polygon #ptgeomL = [] #for pt in ptL: # ptgeomL.append(Point(pt)) self.shapelyGeom = Polygon(ptL) #self.shapelyGeom = Polygon(ptgeomL) self.ShapelyToOgrGeom()
def test_convert_to_geometry_coordinates_multipolygon(self): p1 = 'Polygon ((-116.94238466549290933 52.12861711455555991, -82.00526805089285176 61.59075286434307372, -59.92695130138864101 31.0207758265680269, -107.72286778108455962 22.0438778075388484, -122.76523743459291893 37.08624746104720771, -116.94238466549290933 52.12861711455555991))' p2 = 'Polygon ((-63.08099655131782413 21.31602121140134898, -42.70101185946779765 9.42769680782217279, -65.99242293586783603 9.912934538580501, -63.08099655131782413 21.31602121140134898))' p1 = wkt.loads(p1) p2 = wkt.loads(p2) mp1 = MultiPolygon([p1, p2]) mp2 = mp1.buffer(0.1) geoms = [mp1, mp2] gvar = GeometryVariable(name='gc', value=geoms, dimensions='gd') # Test the element node connectivity arrays. results = [] for pack in [False, True]: gc = gvar.convert_to(pack=pack) self.assertEqual(gc.dimension_map.get_driver(), DriverKey.NETCDF_UGRID) self.assertTrue(gc.has_multi) self.assertIn(OcgisConvention.Name.MULTI_BREAK_VALUE, gc.cindex.attrs) # Test multi-break values are part of the element node connectivity arrays. actual = gc.cindex.get_value() for idx, ii in enumerate(actual.flat): self.assertGreater( np.sum(ii == OcgisConvention.Value.MULTI_BREAK_VALUE), 0) results.append(actual) self.assertIsNotNone(gc.x.get_value()) self.assertIsNotNone(gc.y.get_value()) maxes = [] for ii in actual.flat: maxes.append(ii.max()) actual_max = max(maxes) for c in [gc.x, gc.y]: self.assertEqual(c.size - 1, actual_max) geoms = list(gc.iter_geometries()) for ctr, g in enumerate(geoms): self.assertIsInstance(g[1], BaseMultipartGeometry) self.assertEqual(ctr, 1) self.assertPolygonSimilar(geoms[0][1], mp1) self.assertPolygonSimilar(geoms[1][1], mp2) for idx in range(len(results[0])): self.assertNumpyAll(results[0][idx], results[1][idx])
def to_python(self, value): type = value['type'] if type == 'Polygon': return Polygon(value['coordinates']) elif type == 'MultiPolygon': [Polygon(i) for i in value['coordinates']] return MultiPolygon([Polygon(i) for i in value['coordinates']]) else: raise Exception(f'Type {type} not supported.')
async def upload_working_area( file: UploadFile = File(...), *, organization_id: int, auth=Depends(authorization("organizations:upload_working_area")), db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """ Upload a geo file """ try: filename_parts = os.path.splitext(file.filename) extension = filename_parts[1][1:] if extension not in ["geojson"]: raise HTTPException(status_code=415, detail="File format unsupported") unique_name = uuid.uuid4() unique_filename = f"{unique_name}.{extension}" copy_filename = f"{settings.UPLOADED_FILES_FOLDER}/{unique_filename}" copy_file = await file.read() with open(copy_filename, "wb") as f: f.write(copy_file) # type: ignore c = fiona.open(copy_filename) record = next(iter(c)) if not record["geometry"]["type"]: raise HTTPException(status_code=415, detail="File unsupported") organization_in_db = organization.get(db, id=organization_id) if not organization_in_db: raise HTTPException(status_code=404, detail="Organization not found") shape_working_area = shape(record["geometry"]) working_area = shape_working_area.wkt if record["geometry"]["type"] == "Polygon": working_area = MultiPolygon([shape_working_area]).wkt return organization.update( db, db_obj=organization_in_db, obj_in={ "working_area": working_area }, ).to_schema() finally: os.remove(copy_filename) await file.close()
def test_convert_to_geometry_coordinates_multipolygon(self): p1 = 'Polygon ((-116.94238466549290933 52.12861711455555991, -82.00526805089285176 61.59075286434307372, -59.92695130138864101 31.0207758265680269, -107.72286778108455962 22.0438778075388484, -122.76523743459291893 37.08624746104720771, -116.94238466549290933 52.12861711455555991))' p2 = 'Polygon ((-63.08099655131782413 21.31602121140134898, -42.70101185946779765 9.42769680782217279, -65.99242293586783603 9.912934538580501, -63.08099655131782413 21.31602121140134898))' p1 = wkt.loads(p1) p2 = wkt.loads(p2) mp1 = MultiPolygon([p1, p2]) mp2 = mp1.buffer(0.1) geoms = [mp1, mp2] gvar = GeometryVariable(name='gc', value=geoms, dimensions='gd') # Test the element node connectivity arrays. results = [] for pack in [False, True]: gc = gvar.convert_to(pack=pack) self.assertEqual(gc.dimension_map.get_driver(), DriverKey.NETCDF_UGRID) self.assertTrue(gc.has_multi) self.assertIn(OcgisConvention.Name.MULTI_BREAK_VALUE, gc.cindex.attrs) # Test multi-break values are part of the element node connectivity arrays. actual = gc.cindex.get_value() for idx, ii in enumerate(actual.flat): self.assertGreater(np.sum(ii == OcgisConvention.Value.MULTI_BREAK_VALUE), 0) results.append(actual) self.assertIsNotNone(gc.x.get_value()) self.assertIsNotNone(gc.y.get_value()) maxes = [] for ii in actual.flat: maxes.append(ii.max()) actual_max = max(maxes) for c in [gc.x, gc.y]: self.assertEqual(c.size - 1, actual_max) geoms = list(gc.iter_geometries()) for ctr, g in enumerate(geoms): self.assertIsInstance(g[1], BaseMultipartGeometry) self.assertEqual(ctr, 1) self.assertPolygonSimilar(geoms[0][1], mp1) self.assertPolygonSimilar(geoms[1][1], mp2) for idx in range(len(results[0])): self.assertNumpyAll(results[0][idx], results[1][idx])
def reduce_to_multipolygon(geoms): if type(geoms) not in (list, tuple): geoms = [geoms] polys = [] for geom in geoms: if isinstance(geom, MultiPolygon): for poly in geom: polys.append(poly) else: polys.append(geom) return (MultiPolygon(polys))
def wkt_loads_wrapped(data): p = wkt.loads(data) if isinstance(p, Polygon): p = MultiPolygon([p]) elif isinstance(p, MultiPolygon): pass else: p = p p = WKTElement(p.wkt, srid=4326) return p
def enforce_multipolygon_winding_order(self, shape): assert shape.type == 'MultiPolygon' parts = [] for part in shape.geoms: # see comment in shape.type == 'Polygon' above about why # the sign here has to be -1. part = orient(part, sign=-1.0) parts.append(part) oriented_shape = MultiPolygon(parts) return oriented_shape
def _load_US_boundary(self): """ Loads a GeoJSON multipolygon created separately by merging the polygons provided here: https://developers.google.com/kml/documentation/us_states.kml """ geojson_multipolygon_file = open("united_states_border.json", "r") geojson_multipolygon = json.loads(geojson_multipolygon_file.read()) geojson_multipolygon_file.close() # create a shapely multipolygon - this will be used to determine if a generated grid cell lies within the USA self._US_boundary = MultiPolygon(geojson_multipolygon["coordinates"], context_type = "geojson")
def enforce_multipolygon_winding_order(self, shape, n_try): assert shape.type == 'MultiPolygon' parts = [] for part in shape.geoms: # see comment in shape.type == 'Polygon' above about why # the sign here has to be -1. part = self.enforce_polygon_winding_order(part, n_try) parts.append(part) oriented_shape = MultiPolygon(parts) oriented_shape = self.handle_shape_validity(oriented_shape, n_try) return oriented_shape
def _shift_(geom): try: coords = np.array(geom.exterior.coords) coords[:, 0] = coords[:, 0] - 360 ret = Polygon(coords) except AttributeError: polygons = np.empty(len(geom), dtype=object) for ii, polygon in enumerate(geom): coords = np.array(polygon.exterior.coords) coords[:, 0] = coords[:, 0] - 360 polygons[ii] = Polygon(coords) ret = MultiPolygon(polygons) return (ret)
def wkt_loads_wrapped(data): if not isinstance(data, str): return data p = wkt.loads(data) if isinstance(p, Polygon): p = MultiPolygon([p]) elif isinstance(p, MultiPolygon) or isinstance(p, Point): pass else: p = None if p: p = WKTElement(p.wkt, srid=4326) return p
def test_init(): date = datetime.datetime.now() real_estate = RealEstateRecord(u'test', u'BL', u'Laufen', 2770, 1000, MultiPolygon(), ViewServiceRecord( 'test_link', 'test_legend' )) plr_office = OfficeRecord({u'en': u'PLR Authority'}) resolver = DottedNameResolver() date_method_string = Config.get('extract').get('base_data').get('methods').get('date') date_method = resolver.resolve(date_method_string) av_update_date = date_method(real_estate) base_data = Config.get_base_data(av_update_date) av_provider_method_string = Config.get('extract').get('base_data').get('methods').get('provider') av_provider_method = resolver.resolve(av_provider_method_string) cadaster_state = date theme = ThemeRecord(u'TEST', {u'de': u'TEST TEXT'}) datasources = [DatasourceRecord(theme, date, plr_office)] plr_cadastre_authority = Config.get_plr_cadastre_authority() embeddable = EmbeddableRecord( cadaster_state, plr_cadastre_authority, av_provider_method(real_estate), av_update_date, datasources ) record = ExtractRecord( real_estate, ImageRecord('100'.encode('utf-8')), ImageRecord('100'.encode('utf-8')), ImageRecord('100'.encode('utf-8')), ImageRecord('100'.encode('utf-8')), plr_office, base_data, embeddable ) assert isinstance(record.extract_identifier, str) assert isinstance(record.real_estate, RealEstateRecord) assert isinstance(record.not_concerned_theme, list) assert isinstance(record.concerned_theme, list) assert isinstance(record.theme_without_data, list) assert isinstance(record.creation_date, datetime.date) assert isinstance(record.logo_plr_cadastre, ImageRecord) assert isinstance(record.federal_logo, ImageRecord) assert isinstance(record.cantonal_logo, ImageRecord) assert isinstance(record.municipality_logo, ImageRecord) assert isinstance(record.exclusions_of_liability, list) assert isinstance(record.glossaries, list) assert isinstance(record.plr_cadastre_authority, OfficeRecord) assert isinstance(record.base_data, dict) assert isinstance(record.embeddable, EmbeddableRecord)
def transform_path(self, path): def path_interpolation(path, n_steps): path_verts, path_codes = zip(*list(path.iter_segments(curves=False))) path_verts = np.array(path_verts) path_codes = np.array(path_codes) verts_split_inds = np.where(path_codes == Path.MOVETO)[0] verts_split = np.split(path_verts, verts_split_inds, 0) codes_split = np.split(path_codes, verts_split_inds, 0) v_collection = [] c_collection = [] for path_verts, path_codes in zip(verts_split, codes_split): if len(path_verts) == 0: continue import matplotlib.cbook # print path_verts.shape verts = matplotlib.cbook.simple_linear_interpolation(path_verts, n_steps) v_collection.append(verts) # print verts.shape codes = np.ones(verts.shape[0]) * Path.LINETO codes[0] = Path.MOVETO c_collection.append(codes) return Path(np.concatenate(v_collection), np.concatenate(c_collection)) # print 'transform path:', path # print 'p shape: ', path.vertices, path.vertices.shape if path.vertices.shape == (1, 2): return Path(self.transform_no_mod(path.vertices)) # print '\n'.join(['%s %s' % (point, code) for point, code in path.iter_segments()]) p2 = polygon.Polygon(((-180, -90), (180, -90), (180, 90), (-180, 90))) paths = [] shps = [] for shp in shape_convert.path_to_geos(path): shps = [] for lon in range(-360, 720, 360): # for lon in range(0, 360, 360): if isinstance(shp, polygon.Polygon): c_shp = polygon.Polygon(np.array(shp.exterior) - [lon, 0], [np.array(ring) - [lon, 0] for ring in shp.interiors]) elif isinstance(shp, linestring.LineString): c_shp = linestring.LineString(np.array(shp) - [lon, 0]) elif isinstance(shp, MultiLineString): c_shp = MultiLineString([linestring.LineString(np.array(s) - [lon, 0]) for s in shp.geoms]) else: raise ValueError('Unknown shapely object (%s).' % (type(shp))) shps.append(c_shp) if isinstance(shp, polygon.Polygon): shps = MultiPolygon(shps) elif isinstance(shp, linestring.LineString): shps = MultiLineString(shps) else: ValueError('Unknown shape type') # join the shapes back together again if they have wrapped the entire 360 range. from shapely.ops import cascaded_union shps = cascaded_union(shps) interp_resolution = 40 # try: intersection_shp = shps.intersection(p2) pths = shape_convert.geos_to_path(intersection_shp) # print pths paths.extend([path_interpolation(pth, interp_resolution) for pth in pths]) # print paths # except shapely.geos.TopologicalError: # print 'failed with: ', shps # print 'orig path: ', path # print 'path: ', shape_convert.geos_to_path(shps) # import matplotlib.pyplot as plt # from matplotlib.collections import PatchCollection # import matplotlib.patches as mpatches # import matplotlib.cm # # plt.close() # pth = shape_convert.geos_to_path(shps)[0] # poly = mpatches.PathPatch(pth) # collection = PatchCollection([poly], cmap=matplotlib.cm.jet, alpha=0.4) # plt.gca().add_collection(collection) # plt.show() if len(paths) == 1: path = paths[0] elif len(paths) == 0: return Path(np.empty([0,2])) else: points = [] codes = [] for path in paths: path_points, path_codes = zip(*(path.iter_segments())) points.append(path_points) codes.append(path_codes) points = [np.array(pts) for pts in points] path = Path(np.concatenate(points, 0), np.concatenate(codes)) # print '------------' # print '\n'.join(['%s %s' % (point, code) for point, code in path.iter_segments()]) # print 'll post: ', path.vertices # print path.codes # path = path.interpolated(40) # path = path.interpolated(4) # print path.vertices # print ']]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]' path.vertices = self.transform_no_mod(path.vertices) return path
def transform_path(self, path): def path_interpolation(path, n_steps): path_verts, path_codes = zip(*list(path.iter_segments(curves=False))) path_verts = np.array(path_verts) path_codes = np.array(path_codes) verts_split_inds = np.where(path_codes == Path.MOVETO)[0] verts_split = np.split(path_verts, verts_split_inds, 0) codes_split = np.split(path_codes, verts_split_inds, 0) v_collection = [] c_collection = [] for path_verts, path_codes in zip(verts_split, codes_split): if len(path_verts) == 0: continue import matplotlib.cbook # print path_verts.shape verts = matplotlib.cbook.simple_linear_interpolation(path_verts, n_steps) v_collection.append(verts) # print verts.shape codes = np.ones(verts.shape[0]) * Path.LINETO codes[0] = Path.MOVETO c_collection.append(codes) return Path(np.concatenate(v_collection), np.concatenate(c_collection)) # print 'transform path:', path # print 'p shape: ', path.vertices, path.vertices.shape if path.vertices.shape == (1, 2): return Path(self.transform_no_mod(path.vertices)) # print '\n'.join(['%s %s' % (point, code) for point, code in path.iter_segments()]) # p2 = polygon.Polygon(((-180, -90), (180, -90), (180, 90), (-180, 90))) p2 = self.projection.edge p2 = path_interpolation(p2, 30) p2 = shape_convert.path_to_geos(p2) p2 = p2[0] paths = [] for shp in shape_convert.path_to_geos(path): shps = [] for lon in range(-360, 720, 360): # for lon in range(0, 360, 360): if isinstance(shp, polygon.Polygon): c_shp = polygon.Polygon(np.array(shp.exterior) - [lon, 0], [np.array(ring) - [lon, 0] for ring in shp.interiors]) elif isinstance(shp, linestring.LineString): c_shp = linestring.LineString(np.array(shp) - [lon, 0]) elif isinstance(shp, MultiLineString): c_shp = MultiLineString([linestring.LineString(np.array(s) - [lon, 0]) for s in shp.geoms]) else: raise ValueError('Unknown shapely object (%s).' % (type(shp))) shps.append(c_shp) # Turn the list of shapes into a Geos type if isinstance(shp, polygon.Polygon): shps = MultiPolygon(shps) elif isinstance(shp, linestring.LineString): shps = MultiLineString(shps) else: ValueError('Unknown shape type') # join the shapes back together again if they have wrapped the entire 360 range. shps = cascaded_union(shps) # Do one more intersection of the overall union (this seems to be necessary) intersection_shp = shps.intersection(p2) pths = shape_convert.geos_to_path(intersection_shp) # pths = shape_convert.geos_to_path(shps) # Now interpolate the paths interp_resolution = 15 # interp_resolution = 5 # for pth in pths: # p9 = path_interpolation(pth, 9) ## print '\n------' * 30 ## print 'interp 9:', p9 ## print '\n------' * 5 ## print 'interp 5:', path_interpolation(pth, 5) ## print '\n------' * 30 # paths.append(path_interpolation(pth, 9)) # paths.extend([path_interpolation(pth, interp_resolution) for pth in pths]) if len(paths) == 1: path = paths[0] elif len(paths) == 0: return Path(np.empty([0,2])) else: points = [] codes = [] for path in paths: path_points, path_codes = zip(*(path.iter_segments(curves=False, simplify=False))) points.append(path_points) codes.append(path_codes) points = [np.array(pts) for pts in points] path = Path(np.concatenate(points, 0), np.concatenate(codes)) # print '------------' # print '\n'.join(['%s %s' % (point, code) for point, code in path.iter_segments()]) # print 'll post: ', path.vertices # print path.codes # path = path.interpolated(40) # path = path.interpolated(4) # print path.vertices path.vertices = self.transform_no_mod(path.vertices) return path
class GridGenerator(object): """ This class subdivides the geographical extent of the United States into an equal area grid. Dependencies: /geography_helper.py /equal_area_globe_grid.py /united_states_border.json Usage: Let X be the desired area in square miles of each equal area cell >> GridGenerator(sqrt(X)).run() Output: /beautiful_grid.kml """ def __init__(self, cell_size_miles): # input is desired square of each equal area cell, in miles self._cell_size_miles = cell_size_miles # ecapsulating longitude/latitude boxes for Mainland, Alaska, Hawaii, Puerto Rico self._geo_reference = USABoundsReference().Geographies # we'll store each cell's shape array here self._shape_arrays = [] # a calculator that converts grid (column, row) to (longitude, latitude) and vice versa. # formulas given by the National Snow and Ice Data Center (see EqualAreaGlobeGrid doc-string for more info) self._proj_calc = EqualAreaGlobeGrid(self._cell_size_miles) def run(self): """ Public run method - generates an equal area grid for the United States """ self._load_US_boundary() self._create_equal_area_grid() self._save_to_kml() def _load_US_boundary(self): """ Loads a GeoJSON multipolygon created separately by merging the polygons provided here: https://developers.google.com/kml/documentation/us_states.kml """ geojson_multipolygon_file = open("united_states_border.json", "r") geojson_multipolygon = json.loads(geojson_multipolygon_file.read()) geojson_multipolygon_file.close() # create a shapely multipolygon - this will be used to determine if a generated grid cell lies within the USA self._US_boundary = MultiPolygon(geojson_multipolygon["coordinates"], context_type = "geojson") def _create_equal_area_grid(self): """ For each region in the USA, calculate all equal area cells that either intersect, or are contained within that region. Each cell follows the numbering convention: Northwest Corner: (longitude_0, latitude_0) Northeast Corner: (longitude_1, latitude_1) Southeast Corner: (longitude_2, latitude_2) Southwest Corner: (longitude_3, latitude_3) """ # loop over all boxes bounding the separate US geographical regions (Mainland, Alaska, Hawaii, Puerto Rico) for region in self._geo_reference: # start in the northwest corner of the bounding box region_most_west_longitude = self._geo_reference[region]["west"] region_most_north_latitude = self._geo_reference[region]["north"] # get the starting grid column-row coordinate pair self._r_0, self._s_0 = self._proj_calc.get_grid_coordinates(region_most_west_longitude, region_most_north_latitude) start_longitude, start_latitude = self._proj_calc.get_longitude_latitude(self._r_0, self._s_0) # just renaming to keep the crawl semantically consistent latitude_crawl = start_latitude # row index relative to s_0 s = 0 # crawl southward while latitude_crawl > self._geo_reference[region]["south"]: # column index relative to r_0 r = 0 # reset the starting longitude (western-most of the region on the grid) longitude_crawl = start_longitude # crawl eastward while longitude_crawl < self._geo_reference[region]["east"]: # generate a cell, and return the new starting longitude and latitude longitude_crawl, latitude_crawl = self._generate_individual_cell(r, s) r += 1 s += 1 def _generate_individual_cell(self, r, s): # northwest corner longitude_0, latitude_0 = self._proj_calc.get_longitude_latitude(self._r_0 + r, self._s_0 + s) # northeast corner longitude_1, latitude_1 = self._proj_calc.get_longitude_latitude(self._r_0 + r + 1, self._s_0 + s) # southeast corner longitude_2, latitude_2 = self._proj_calc.get_longitude_latitude(self._r_0+ r + 1, self._s_0 + s + 1) # southwest corner longitude_3, latitude_3 = self._proj_calc.get_longitude_latitude(self._r_0 + r, self._s_0 + s + 1) shape_array = [ [longitude_0, latitude_0], [longitude_1, latitude_1], [longitude_2, latitude_2], [longitude_3, latitude_3], [longitude_0, latitude_0] ] # only add the shape array to the master list if it intersects or is contained within the USA if self._shape_is_in_US(shape_array): self._shape_arrays.append(shape_array) return longitude_3, latitude_0 def _shape_is_in_US(self, shape_array): # create shapely polygon out of the shape array square = Polygon(shape_array) # true if square either intersects the border of _US_boundary, or if it is included within the boundary return self._US_boundary.intersects(square) def _save_to_kml(self): """ Creates a KML file of this grid viewable in Google Maps and Google Earth. See https://developers.google.com/kml/documentation/ """ # call a helper method to convert this array of shape arrays to a KML file kml_text = convert_arrays_of_geocos_to_kml(self._shape_arrays) # save to a file in this directory beautiful_grid_file = open("beautiful_grid.kml", "w") beautiful_grid_file.write(kml_text) beautiful_grid_file.close()