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,
        ))
Пример #2
0
    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")
Пример #4
0
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
Пример #5
0
 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)
Пример #6
0
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
Пример #7
0
 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()
Пример #8
0
    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)
Пример #9
0
 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
Пример #10
0
    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)
Пример #11
0
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()
Пример #12
0
    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
Пример #13
0
 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)
Пример #14
0
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
Пример #15
0
    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
Пример #16
0
    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)
Пример #17
0
    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)
Пример #18
0
    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))
Пример #19
0
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)
Пример #20
0
 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'])
Пример #21
0
 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()
Пример #22
0
    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])
Пример #23
0
 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.')
Пример #24
0
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()
Пример #25
0
    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])
Пример #26
0
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))
Пример #27
0
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
Пример #28
0
    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")
Пример #30
0
    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
Пример #31
0
 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
Пример #33
0
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)
Пример #34
0
    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
Пример #35
0
    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()