Пример #1
0
def test_shapely_intersection():
    """Testing Shapely: Test against prepared geometry intersection bug #603"""
    # http://trac.osgeo.org/geos/ticket/603
    from shapely.geometry import MultiPolygon, box
    from shapely.prepared import prep
    from shapely import wkt

    assert MultiPolygon([box(0, 0, 1, 10), box(40, 0, 41, 10)]).intersects(box(20, 0, 21, 10)) == False
    assert prep(MultiPolygon([box(0, 0, 1, 10), box(40, 0, 41, 10)])).intersects(box(20, 0, 21, 10)) == False

    # tile_grid(3857, origin='nw').tile_bbox((536, 339, 10))
    tile = box(939258.2035682462, 6731350.458905761, 978393.9620502564, 6770486.217387771)
    tile = box(978393.9620502554, 6770486.217387772, 1017529.7205322656, 6809621.975869782)
    # "{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"type":"box_control"},"geometry":{"type":"Polygon","coordinates":[[[1449611.9686912997,6878109.5532215],[1449611.9686912997,6909907.3569881],[1476517.8026477,6909907.3569881],[1476517.8026477,6878109.5532215],[1449611.9686912997,6878109.5532215]]]}},{"type":"Feature","properties":{"type":"box_control"},"geometry":{"type":"Polygon","coordinates":[[[909049.30465869,6435386.285393901],[909049.30465869,6457400.14954],[943293.0933304401,6457400.14954],[943293.0933304401,6435386.285393901],[909049.30465869,6435386.285393901]]]}}]}"
    coverage = wkt.loads(
        "MULTIPOLYGON ("
            "((1449611.9686912996694446 6878109.5532214995473623, "
              "1449611.9686912996694446 6909907.3569881003350019, "
              "1476517.8026477000676095 6909907.3569881003350019, "
              "1476517.8026477000676095 6878109.5532214995473623, "
              "1449611.9686912996694446 6878109.5532214995473623)), "
            "((909049.3046586900018156 6435386.2853939011693001, "
              "909049.3046586900018156 6457400.1495399996638298, "
              "943293.0933304401114583 6457400.1495399996638298, "
              "943293.0933304401114583 6435386.2853939011693001, "
              "909049.3046586900018156 6435386.2853939011693001)))"
    )
    assert prep(coverage).contains(tile) == False
    assert prep(coverage).intersects(tile) == False
Пример #2
0
    def __init__(self,
                 regions_file=REGIONS_FILE,
                 buffer_file=REGIONS_BUFFER_FILE):
        self._buffered_shapes = {}
        self._prepared_shapes = {}
        self._shapes = {}
        self._tree_ids = {}
        self._radii = {}

        with util.gzip_open(regions_file, 'r') as fd:
            regions_data = simplejson.load(fd)

        genc_regions = frozenset([rec.alpha2 for rec in genc.REGIONS])
        for feature in regions_data['features']:
            code = feature['properties']['alpha2']
            if code in genc_regions:
                shape = geometry.shape(feature['geometry'])
                self._shapes[code] = shape
                self._prepared_shapes[code] = prepared.prep(shape)
                self._radii[code] = feature['properties']['radius']

        with util.gzip_open(buffer_file, 'r') as fd:
            buffer_data = simplejson.load(fd)

        i = 0
        envelopes = []
        for feature in buffer_data['features']:
            code = feature['properties']['alpha2']
            if code in genc_regions:
                shape = geometry.shape(feature['geometry'])
                self._buffered_shapes[code] = prepared.prep(shape)
                # Collect rtree index entries, and maintain a separate id to
                # code mapping. We don't use index object support as it
                # requires un/pickling the object entries on each lookup.
                if isinstance(shape, geometry.base.BaseMultipartGeometry):
                    # Index bounding box of individual polygons instead of
                    # the multipolygon, to avoid issues with regions crossing
                    # the -180.0/+180.0 longitude boundary.
                    for geom in shape.geoms:
                        envelopes.append((i, geom.envelope.bounds, None))
                        self._tree_ids[i] = code
                        i += 1
                else:
                    envelopes.append((i, shape.envelope.bounds, None))
                    self._tree_ids[i] = code
                    i += 1

        props = index.Property()
        props.fill_factor = 0.9
        props.leaf_capacity = 20
        self._tree = index.Index(envelopes,
                                 interleaved=True, properties=props)
        for envelope in envelopes:
            self._tree.insert(*envelope)
        self._valid_regions = frozenset(self._shapes.keys())
Пример #3
0
    def __init__(self, json_file=JSON_FILE):
        self._buffered_shapes = {}
        self._prepared_shapes = {}
        self._shapes = {}
        self._tree_ids = {}
        self._radii = {}

        with util.gzip_open(json_file, 'r') as fd:
            data = simplejson.load(fd)

        genc_regions = frozenset([rec.alpha2 for rec in genc.REGIONS])
        for feature in data['features']:
            code = feature['properties']['alpha2']
            if code in genc_regions:
                shape = geometry.shape(feature['geometry'])
                self._shapes[code] = shape
                self._prepared_shapes[code] = prepared.prep(shape)
                self._radii[code] = feature['properties']['radius']

        i = 0
        envelopes = []
        for code, shape in self._shapes.items():
            # Build up region buffers, to create shapes that include all of
            # the coastal areas and boundaries of the regions and anywhere
            # a cell signal could still be recorded. The value is in decimal
            # degrees (1.0 == ~100km) but calculations don't take projection
            # / WSG84 into account.
            # After buffering remove any parts that crosses the -180.0/+180.0
            # longitude boundary to the east or west.
            buffered = (shape.buffer(0.5)
                             .difference(DATELINE_EAST)
                             .difference(DATELINE_WEST))
            self._buffered_shapes[code] = prepared.prep(buffered)

            # Collect rtree index entries, and maintain a separate id to
            # code mapping. We don't use index object support as it
            # requires un/pickling the object entries on each lookup.
            if isinstance(buffered, geometry.base.BaseMultipartGeometry):
                # Index bounding box of individual polygons instead of
                # the multipolygon, to avoid issues with regions crossing
                # the -180.0/+180.0 longitude boundary.
                for geom in buffered.geoms:
                    envelopes.append((i, geom.envelope.bounds, None))
                    self._tree_ids[i] = code
                    i += 1
            else:
                envelopes.append((i, buffered.envelope.bounds, None))
                self._tree_ids[i] = code
                i += 1

        props = index.Property()
        props.fill_factor = 0.9
        props.leaf_capacity = 20
        self._tree = index.Index(envelopes, interleaved=True, properties=props)
        self._valid_regions = frozenset(self._shapes.keys())
Пример #4
0
def test_prepare_already_prepared():
    polygon = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
    prepared = prep(polygon)
    # attempt to prepare an already prepared geometry with `prep`
    result = prep(prepared)
    assert isinstance(result, PreparedGeometry)
    assert result.context is polygon
    # attempt to prepare an already prepared geometry with `PreparedGeometry`
    result = PreparedGeometry(prepared)
    assert isinstance(result, PreparedGeometry)
    assert result.context is polygon
Пример #5
0
    def _rings_to_multi_polygon(self, rings, is_ccw):
        exterior_rings = []
        interior_rings = []
        for ring in rings:
            if ring.is_ccw != is_ccw:
                interior_rings.append(ring)
            else:
                exterior_rings.append(ring)

        polygon_bits = []

        # Turn all the exterior rings into polygon definitions,
        # "slurping up" any interior rings they contain.
        for exterior_ring in exterior_rings:
            polygon = sgeom.Polygon(exterior_ring)
            prep_polygon = prep(polygon)
            holes = []
            for interior_ring in interior_rings[:]:
                if prep_polygon.contains(interior_ring):
                    holes.append(interior_ring)
                    interior_rings.remove(interior_ring)
            polygon_bits.append((exterior_ring.coords, [ring.coords for ring in holes]))

        # Any left over "interior" rings need "inverting" with respect
        # to the boundary.
        if interior_rings:
            boundary_poly = self.domain
            x3, y3, x4, y4 = boundary_poly.bounds
            bx = (x4 - x3) * 0.1
            by = (y4 - y3) * 0.1
            x3 -= bx
            y3 -= by
            x4 += bx
            y4 += by
            for ring in interior_rings:
                polygon = sgeom.Polygon(ring)
                if polygon.is_valid:
                    x1, y1, x2, y2 = polygon.bounds
                    bx = (x2 - x1) * 0.1
                    by = (y2 - y1) * 0.1
                    x1 -= bx
                    y1 -= by
                    x2 += bx
                    y2 += by
                    box = sgeom.box(min(x1, x3), min(y1, y3), max(x2, x4), max(y2, y4))

                    # Invert the polygon
                    polygon = box.difference(polygon)

                    # Intersect the inverted polygon with the boundary
                    polygon = boundary_poly.intersection(polygon)

                    if not polygon.is_empty:
                        polygon_bits.append(polygon)

        if polygon_bits:
            multi_poly = sgeom.MultiPolygon(polygon_bits)
        else:
            multi_poly = sgeom.MultiPolygon()
        return multi_poly
    def _set_mapdata(self):
        self.df_map = pd.DataFrame({
            'poly': [Polygon(points) for points in self.map.seattle],
            'name': [hood[self.section_name] for hood in self.map.seattle_info]
        })

        self.hood_polygons = prep(MultiPolygon(list(self.df_map['poly'].values)))
Пример #7
0
def cover_geometry(tilescheme, geom, zoom):
    """Covers the provided geometry with tiles.

    Args:
        tilescheme: The tile scheme to use.  This needs to implement
                    the public protocal of the schemes defined within
                    tiletanic.
        geom: The geometry we would like to cover.  This should be a
              shapely geometry.
        zoom: The zoom level of the tiles to cover geom with.

    Yields:
        An iterator of Tile objects ((x, y, z) named tuples) that
        cover the input geometry.
    """
    # Only shapely geometries allowed.
    if not isinstance(geom, geometry.base.BaseGeometry):
        raise ValueError("Input 'geom' is not a known shapely geometry type")
    
    if geom.is_empty:
        return

    # Generate the covering.
    prep_geom = prepared.prep(geom)    
    if isinstance(geom, (geometry.Polygon, geometry.MultiPolygon)):        
        for tile in _cover_polygonal(tilescheme, Tile(0, 0, 0), prep_geom, geom, zoom):
            yield tile
    else:
        for tile in _cover_geometry(tilescheme, Tile(0, 0, 0), prep_geom, geom, zoom):
            yield tile
Пример #8
0
    def iter_intersects(self, shapely_geom, geom_mapping, keep_touches=True):
        """
        Return an interator for the unique identifiers of the geometries intersecting the target geometry.

        :param :class:`shapely.geometry.Geometry` shapely_geom: The geometry to use for subsetting. It is the ``bounds``
         attribute fo the geometry that is actually tested.
        :param dict geom_mapping: The collection of geometries to do the full intersects test on. The keys of the
         dictionary correspond to the integer unique identifiers. The values are Shapely geometries.
        :param bool keep_touches: If ``True``, return the unique identifiers of geometries only touching the subset
         geometry.
        :returns: Generator yield integer unique identifiers.
        :rtype: int
        """
        # Create the geometry iterator. If it is a multi-geometry, we want to iterator over those individually.
        try:
            itr = iter(shapely_geom)
        except TypeError:
            # likely not a multi-geometry
            itr = [shapely_geom]

        for shapely_geom_sub in itr:
            # Return the initial identifiers that intersect with the bounding box using the retree internal method.
            ids = self._get_intersection_rtree_(shapely_geom_sub)
            # Prepare the geometry for faster operations.
            prepared = prep(shapely_geom_sub)
            _intersects = prepared.intersects
            _touches = shapely_geom_sub.touches
            for ii in ids:
                geom = geom_mapping[ii]
                if _intersects(geom):
                    if keep_touches == False:
                        if _touches(geom) == False:
                            yield (ii)
                    else:
                        yield (ii)
Пример #9
0
def _tiles_inside_geom(tilescheme, tiles, geom):
    """Filters out tiles do not contain the geometry geom

    Consider the nine adjacent tiles:

       -------------
       | 1 | 2 | 3 |
       -------------
       | 4 | 5 | 6 |
       -------------
       | 7 | 8 | 9 |
       -------------

    if the AOI is 5, _tiles_inside_geom will only return 5.  Note that
    tiletanic.tilecover.cover_geometry returns all 9 tiles

    Args:
      tilescheme: The tile scheme to use.
      tiles: list iterable collection of tiles
      geom: Shapely Geometry area of interest
    """
    prep_geom = prepared.prep(geom)
    for t in tiles:
        coords = tilescheme.bbox(t)
        tile_geom = geometry.Polygon(((coords.xmin, coords.ymin),
                                      (coords.xmax, coords.ymin),
                                      (coords.xmax, coords.ymax),
                                      (coords.xmin, coords.ymax),
                                      (coords.xmin, coords.ymin)))

        # Touches: The Geometries have at least one boundary point in
        # common, but no interior points
        if not prep_geom.touches(tile_geom):
            yield t
Пример #10
0
    def _get_level_geometries(level):
        buildings = level.buildings.all()
        buildings_geom = cascaded_union([building.geometry for building in buildings])
        spaces = {space.pk: space for space in level.spaces.all()}
        holes_geom = []
        for space in spaces.values():
            if space.outside:
                space.geometry = space.geometry.difference(buildings_geom)
            columns = [column.geometry for column in space.columns.all()]
            if columns:
                columns_geom = cascaded_union([column.geometry for column in space.columns.all()])
                space.geometry = space.geometry.difference(columns_geom)
            holes = [hole.geometry for hole in space.holes.all()]
            if holes:
                space_holes_geom = cascaded_union(holes)
                holes_geom.append(space_holes_geom.intersection(space.geometry))
                space.geometry = space.geometry.difference(space_holes_geom)

        for building in buildings:
            building.original_geometry = building.geometry

        if holes_geom:
            holes_geom = cascaded_union(holes_geom)
            holes_geom_prep = prepared.prep(holes_geom)
            for obj in buildings:
                if holes_geom_prep.intersects(obj.geometry):
                    obj.geometry = obj.geometry.difference(holes_geom)

        results = []
        results.extend(buildings)
        for door in level.doors.all():
            results.append(door)

        results.extend(spaces.values())
        return results
Пример #11
0
def clip(coll,igeom):
    '''Do an intersects + intersection and set weights based on geometry
    areas.
    
    coll :: OcgCollection
    igeom :: Shapely Polygon or MultiPolygon
    
    returns
    
    OcgCollection'''
    
    ## logic for convenience. just return the provided collection if a NoneType
    ## is passed for the 'igeom' arugment
    if igeom is not None:
        ## take advange of shapely speedups
        prep_igeom = prepared.prep(igeom)
        ## the weight array
        weights = np.empty(coll.gid.shape,dtype=float)
        weights = np.ma.array(weights,mask=coll.gid.mask)
        ## do the spatial operation
        for idx,geom in iter_array(coll.geom_masked,
                                   return_value=True):
#            import ipdb;ipdb.set_trace()
            if keep(prep_igeom,igeom,geom):
#                import ipdb;ipdb.set_trace()
                new_geom = igeom.intersection(geom)
                weights[idx] = new_geom.area
                coll.geom[idx] = new_geom
        ## set maximum weight to one
        coll.weights = weights/weights.max()
    return(coll)
Пример #12
0
    def intersects(self,polygon):
        ## do the initial grid subset
        grid = self.grid.subset(polygon=polygon)
        ## a prepared polygon
        prep_polygon = prepared.prep(polygon)
        ## the fill arrays
        geom = np.ones(grid.shape,dtype=object)
        geom = np.ma.array(geom,mask=True)
        geom_mask = geom.mask
        
        try:
            row = grid.row.value
            col = grid.column.value
            for ii,jj in product(range(row.shape[0]),range(col.shape[0])):
                pt = Point(col[jj],row[ii])
                geom[ii,jj] = pt
                if prep_polygon.intersects(pt):
                    geom_mask[ii,jj] = False
                else:
                    geom_mask[ii,jj] = True
        ## NcGridMatrixDimension correction
        except AttributeError:
            _row = grid.row
            _col = grid.column
            for ii,jj in iter_array(_row):
                pt = Point(_col[ii,jj],_row[ii,jj])
                geom[ii,jj] = pt
                if prep_polygon.intersects(pt):
                    geom_mask[ii,jj] = False
                else:
                    geom_mask[ii,jj] = True
            
        ret = self.__class__(grid=grid,geom=geom,uid=grid.uid)

        return(ret)
Пример #13
0
 def select_values(self,igeom=None,clip=False):
     ## if an intersection geometry is passed, use it to calculate the weights
     ## but do not modify the geometry. this weight is used to select values
     ## to keep for set statistics.
     
     ## this is the case of no intersection geometry. basically, requesting
     ## the entire dataset.
     if clip and igeom is None:
         mask = np.zeros(self.value_shape)
     elif clip and igeom is not None:
         prep_igeom = prepared.prep(igeom)
         for ii,geom in enumerate(self.geometry):
             if keep(prep_igeom,igeom,geom):
                 new_geom = igeom.intersection(geom)
                 weight = new_geom.area/geom.area
                 assert(weight != 0.0) #tdk
                 self.weight[ii] = weight
         ## it has now been clipped
         clip = False
     if not clip:
         ## loop through the weights determining which values to maintain based
         ## on weights.
         idx = []
         for ii,weight in enumerate(self.weight):
             if weight > 0.5:
                 idx.append(ii)
             elif weight == 0.5:
                 warn('0.5 weight encountered. Removing it.')
         ## select the data and store in special variable for use by set statistics
         mask = np.ones(self.value.shape)
         mask[:,:,idx] = 0
     self.value_set = np.ma.masked_array(self.value,mask=mask)
Пример #14
0
def CreatePointObjects(BasemapTemplate, MapData, ComplaintData):
    ''' Here we create a community geometry object from the combined community polygons.  
    We've done this to speed up membership checking. We perform 
    the check by creating a mutipolygon from map_points, then filtering using 
    the contains() method, which returns all points that are contains within 
    community_poygons. The results is a pandas series returning NYCPoints, which we'll use to make out maps. 
    '''
    
    # Create Point objects (in a pandas Series) in map coordinates from our DataFrame longitude and latitude values.
    # Note that the zip function here aggregates the long/lat data for each observation in our compliant data. 
    # The purpose of this code is to convert our latitude and longitude into Basemap cartesian map coordinates 
    
    MapPoints = pd.Series([Point(BasemapTemplate(MapX, MapY)) for MapX, MapY in zip(ComplaintData['Longitude'], ComplaintData['Latitude'])])
        
    # Creates a MultiPoint object from the list of lat/long values from above. 
    
    ComplaintPoints = MultiPoint(list(MapPoints.values))
    
    #  Use the prep method to give this MultiPolygon object (created from the earlier DataFrame of complaint locations), so that it 
    #  has the 'contains' method, which we'll use in the next step. 
    
    CommunityPolygon = prep(MultiPolygon(list(MapData['poly'].values)))
    
    # calculate points that fall within the community boundaries. Here NYCPoints 
    # is a list containing Point objects of all the complaint points contained in 
    # the community polygons.
    
    NYCPoints = filter(CommunityPolygon.contains, ComplaintPoints)
    
    return (NYCPoints)
Пример #15
0
    def initialize_grid(self, geom):
        """
        """

        bounds = geom.bounds

        (minx, miny, maxx, maxy) = bounds

        (minx, miny, maxx, maxy) = (
            round(np.floor(minx * self.psi)) / self.psi,
            round(np.floor(miny * self.psi)) / self.psi,
            round(np.ceil(maxx * self.psi)) / self.psi,
            round(np.ceil(maxy * self.psi)) / self.psi)

        clean_bounds = (minx, miny, maxx, maxy)

        top_left_lon = minx
        top_left_lat = maxy
        affine = Affine(self.pixel_size, 0, top_left_lon,
                        0, -self.pixel_size, top_left_lat)


        # base_rasterize, base_bounds = self.rasterize_geom(geom)
        # self.shape = base_rasterize.shape

        nrows = int(np.ceil( (maxy - miny) / self.pixel_size ))
        ncols = int(np.ceil( (maxx - minx) / self.pixel_size ))
        self.shape = (nrows, ncols)


        self.bounds = clean_bounds
        self.affine = affine
        self.topleft = (top_left_lon, top_left_lat)
        self.grid_box = prep(box(*self.bounds))
Пример #16
0
    def update(self, transect):
        """
        Gather the data near the transect. Depth convert if necessary.

        Returns nothing. Side effect: sets attributes.

        Args:
            transect (LineString): A shapely LineString object.
        """
        Notice.info("Updating " + self.__class__.__name__)

        b = self.settings.get('fine_buffer') or self.settings['buffer']
        prepared = prep(transect.buffer(b))

        for horizon, points in self.lookup.items():
            l = len(points)
            points = filter(prepared.contains, points)
            print horizon, len(points), "of", l, "points"
            data, coords = [], []
            for p in points:
                coords.append(transect.project(p))
                if self.domain.lower() in ['depth', 'd', 'z']:
                    "Depth converting horizon"
                    zpt = self.velocity.time2depthpt(p.z/1000, coords[-1])
                    data.append(zpt)
                else:
                    data.append(p.z)

            self.data[horizon] = np.array(data)
            self.coords[horizon] = np.array(coords)
    def associate_nodes(fargs):
        """ Find nodes which are within the hull """
        cluster, cluster_hull, nodes = fargs
        # There is no hull for this community, it's been deleted.
        # Orphan all nodes.
        if cluster_hull is None:
            log.info("Missing hull, orphaning all nodes in cluster %i",
                     cluster)
            output = [topotools.NodeInfo(
                orphan.id, orphan.lat, orphan.lon, -1)
                for orphan in nodes]
            return len(output), output

        characteristic_size = math.sqrt(cluster_hull.area)
        allowed_distance = characteristic_size * args.buffer
        buffered = prep(cluster_hull.buffer(allowed_distance))

        output = []
        num_orphans = 0
        for node in nodes:
            # check if it is an interior node
            point = Point((node.lon, node.lat))
            orphan = not buffered.contains(point)
            if orphan:
                num_orphans += 1
            output.append(topotools.NodeInfo(
                node.id, node.lat, node.lon,
                -1 if orphan else node.clust))
        return num_orphans, output
Пример #18
0
def run_tests(bbox, service_url, status_path=None):
    with fiona.open("ne_10m_land.geojson", "r") as source:
        n = source.next()
        land_polygon = prep(shape(n["geometry"]))

    features = []
    session = requests.Session()

    for lon in range(bbox[0], bbox[2]):
        for lat in range(bbox[1], bbox[3]):

            test_coords = []
            for x_offset in range(1, 4):
                for y_offset in range(1, 4):
                    test_coords.append((lon + x_offset / 4.0, lat + y_offset / 4.0))

            point_on_land = False
            for coord in test_coords:
                point = Point(coord[0], coord[1])
                if land_polygon.contains(point):
                    point_on_land = True
                    break

            if not point_on_land:
                logging.debug("No points on land, %f,%f" % (lon, lat))
                continue

            hgt_filename = "%s%02i%s%03i.hgt" % ("N" if lat > 0 else "S", abs(lat), "W" if lon < 0 else "E", abs(lon))

            elevation = test(test_coords, service_url, session=session)
            logging.debug("%i, %i response:%i" % (lon, lat, elevation))
            color = SUCCESS_COLOR
            if elevation == -9999:
                logging.info("fail %i,%i" % (lon, lat))
                color = ERROR_COLOR
            elif elevation == 0:
                logging.info("maybe fail %i,%i" % (lon, lat))
                color = POSSIBLE_ERROR_COLOR
            status_feature = {
                "type": "Feature",
                "properties": {
                    "result": elevation,
                    "hgt": hgt_filename,
                    "points": ";".join([",".join([str(f) for f in c]) for c in test_coords]),
                    "fill-opacity": 0.5,
                    "fill": color,
                    "stroke": "#000000",
                    "stroke-width": 1,
                },
                "geometry": {
                    "type": "Polygon",
                    "coordinates": [[[lon, lat], [lon, lat + 1], [lon + 1, lat + 1], [lon + 1, lat], [lon, lat]]],
                },
            }
            features.append(status_feature)
            if status_path is not None and len(features) % 100 == 0:
                write_feature_collection(features, path=status_path)

    if status_path is not None:
        write_feature_collection(features, path=status_path)
Пример #19
0
    def load_polygons(cls, filename):
        feature_collection = json.load(open(filename))
        polygons = []
        for feature in feature_collection['features']:
            poly_type = feature['geometry']['type']

            if poly_type == 'Polygon':
                poly = Polygon(feature['geometry']['coordinates'][0])
                polygons.append((feature['properties'], prep(poly)))
            elif poly_type == 'MultiPolygon':
                polys = []
                for coords in feature['geometry']['coordinates']:
                    poly = Polygon(coords[0])
                    polys.append(poly)

                polygons.append((feature['properties'], prep(MultiPolygon(polys))))
        return polygons
Пример #20
0
 def load_polygons(cls, filename):
     f = open(filename)
     polygons = {}
     cls.i = 0
     for line in f:
         feature = json.loads(line.rstrip())
         polygons[cls.i] = prep(cls.polygon_from_geojson(feature))
         cls.i += 1
     return polygons
Пример #21
0
 def __init__(self, field, filter_value, negation):
     self.field = field
     self.filter_value = filter_value
     self.prepared = prep(self.filter_value)
     self.negation = negation
     if negation:
         self.evaluate = lambda x: not(self._evaluate(x))
     else:
         self.evaluate = self._evaluate
Пример #22
0
    def load_polygons(cls, filename):
        f = open(filename)
        polygons = []
        for line in f:
            feature = json.loads(line.rstrip())
            poly_type = feature['geometry']['type']

            if poly_type == 'Polygon':
                poly = Polygon(feature['geometry']['coordinates'][0])
                polygons.append((feature['properties'], prep(poly)))
            elif poly_type == 'MultiPolygon':
                polys = []
                for coords in feature['geometry']['coordinates']:
                    poly = Polygon(coords[0])
                    polys.append(poly)

                polygons.append((feature['properties'], prep(MultiPolygon(polys))))
        return polygons
Пример #23
0
    def intersect(self, **kwargs):
        """
            Intersect a Line or Point Collection and the Shoreline

            Returns the point of intersection along the coastline
            Should also return a linestring buffer around the interseciton point
            so we can calculate the direction to bounce a particle.
        """
        ls = None
        if "linestring" in kwargs:
            ls = kwargs.pop('linestring')
            spoint = Point(ls.coords[0])
            epoint = Point(ls.coords[-1])
        elif "start_point" and "end_point" in kwargs:
            spoint = kwargs.pop('start_point')
            epoint = kwargs.pop('end_point')
            ls = LineString(list(spoint.coords) + list(epoint.coords))
        else:
            raise TypeError( "must provide a LineString geometry object or (2) Point geometry objects" )

        inter = False

        # If the current point lies outside of our current shapefile index,
        # re-query the shapefile in a buffer around this point
        if self._spatial_query_object and not ls.within(self._spatial_query_object):
            self.index(point=spoint)

        for element in self._geoms:
            prepped_element = prep(element)

            # Test if starting on land
            if prepped_element.contains(spoint):
                raise Exception('Starting point on land')

            inter = ls.intersection(element)
            if inter:
                # Return the first point in the linestring, and the linestring that it hit
                if isinstance(inter, MultiLineString):
                    inter = inter.geoms[0]

                inter = Point(inter.coords[0])
                smaller_int = inter.buffer(self._spatialbuffer)
                shorelines = element.exterior.intersection(smaller_int)
                if isinstance(shorelines, LineString):
                    shorelines = [shorelines]
                else:
                    shorelines = list(shorelines)

                for shore_segment in shorelines:
                    # Once we find the linestring in the Polygon that was
                    # intersected, break out and return
                    if ls.touches(shore_segment):
                        break

                return {'point': Point(inter.x, inter.y, 0), 'feature': shore_segment or None}
        return None
Пример #24
0
 def get_polygon_cached(self, i):
     poly = self.polygons.get(i, None)
     if poly is None:
         data = json.loads(self.polygons_db.Get(self.polygon_key(i)))
         poly = prep(self.polygon_from_geojson(data))
         self.polygons[i] = poly
         self.cache_misses += 1
     else:
         self.cache_hits += 1
     return poly
Пример #25
0
    def tiles_from_geom(self, geometry, zoom):
        """
        Return all tiles intersecting with input geometry.

        - geometry: shapely geometry
        - zoom: zoom level
        """
        try:
            assert geometry.is_valid
        except AssertionError:
            try:
                clean = geometry.buffer(0.0)
                assert clean.is_valid
                assert clean.area > 0
                geometry = clean
            except AssertionError:
                raise IOError(
                    str(
                        "invalid geometry could not be fixed: '%s'" %
                        explain_validity(geometry)
                        )
                    )
        if geometry.almost_equals(geometry.envelope, ROUND):
            for tile in self.tiles_from_bbox(geometry, zoom):
                yield tile
        elif geometry.geom_type == "Point":
            lon, lat = list(geometry.coords)[0]
            tilelon = self.left
            tilelat = self.top
            tile_x_size = self.tile_x_size(zoom)
            tile_y_size = self.tile_y_size(zoom)
            col = -1
            row = -1
            while tilelon < lon:
                tilelon += tile_x_size
                col += 1
            while tilelat > lat:
                tilelat -= tile_y_size
                row += 1
            yield self.tile(zoom, row, col)
        elif geometry.geom_type in (
            "LineString", "MultiLineString", "Polygon", "MultiPolygon",
            "MultiPoint", "GeometryCollection"
        ):
            prepared_geometry = prep(
                clip_geometry_to_srs_bounds(geometry, self)
                )
            for tile in self.tiles_from_bbox(geometry, zoom):
                if prepared_geometry.intersects(tile.bbox()):
                    yield tile
        elif geometry.is_empty:
            pass
        else:
            raise ValueError("ERROR: no valid geometry: %s" % geometry.type)
Пример #26
0
def country_finder(geo_coord, bbox_hits, polygon_df, m):
    from shapely.geometry import Point
    from shapely.prepared import prep

    inpoint = Point(m(geo_coord.lon,geo_coord.lat))
    region=polygon_df[polygon_df['region_name'].isin(bbox_hits)]

    pgon_list = [idx  for idx, pgon in enumerate([prep(pgon) for pgon in region['poly']])\
                 if pgon.contains(inpoint)]

    return region.iloc[pgon_list]
Пример #27
0
 def revmatches():
     for row,shp in izip(subdict["refdata"].reader.iterRecords(), subdict["refdata"].reader.iterShapes()):
         #if dict(zip(self.fields, row))["SOV0NAME"] != "Russia": continue
         #print "...",row[1] #row[4],row[14]
         print str(row)[:100]
         prepped = prep(asShape(shp)) # prepares geometry for many intersection tests (maybe only useful if is polygon and other is points, but not sure)
         bbox = [shp.points[0][0],shp.points[0][1],shp.points[0][0],shp.points[0][1]] if shp.shapeType == pyshp.POINT else shp.bbox
         ilist = self.spindex.intersection(bbox)
         for i in ilist:
             othershp = self.reader.shape(i)
             if prepped.intersects(asShape(othershp)):
                 yield row,i
Пример #28
0
    def _construct_polygon_map(self, polygon_generator, closest=False):
        """Turn a (tz, polygon) generator, into our internal mapping."""
        self.timezoneNamesToPolygons = collections.defaultdict(list)
        self.unprepTimezoneNamesToPolygons = collections.defaultdict(list)

        for (tzname, raw_poly) in polygon_generator:
            poly = Polygon(tzwhere._raw_poly_to_poly(raw_poly))
            self.timezoneNamesToPolygons[tzname].append(
                prep(poly))
            if closest:
                self.unprepTimezoneNamesToPolygons[tzname].append(
                    poly)
Пример #29
0
    def _construct_shapely_map(self, polygon_generator, forceTZ):
        """Turn a (tz, polygon) generator, into our internal shapely mapping."""
        self.timezoneNamesToPolygons = collections.defaultdict(list)
        self.unprepTimezoneNamesToPolygons = collections.defaultdict(list)

        for (tzname, poly) in polygon_generator:
            poly = Polygon(poly)
            self.timezoneNamesToPolygons[tzname].append(
                prep(poly))
            if forceTZ:
                self.unprepTimezoneNamesToPolygons[tzname].append(
                    poly)
Пример #30
0
def SummarizeByCommunity(MapData, NYCPoints):
    """Create some additional columns, containing the number of points in each NYC community, and the density 
    per square meter and square kilometer community. Normalizing allows us to compare communities."""
        
    MapData['count'] = MapData['poly'].map(lambda x: int(len(filter(prep(x).contains, NYCPoints))))
    MapData['density_m'] = MapData['count'] / MapData['area_m']
    MapData['density_km'] = MapData['count'] / MapData['area_km']
    
    # it's easier to work with NaN values when classifying, so replace zeros with NaNs when appropriate.
    MapData.replace(to_replace={'density_m': {0: np.nan}, 'density_km': {0: np.nan}}, inplace=True)
    
    return MapData
Пример #31
0
 def __init__(self):
     # filterfn = '/home/behry/workspace/eew/reports/data/california_filter_revised.txt'
     filterfn = '/home/behry/workspace/eew/reports/data/SoCalfilter.txt'
     lon, lat = np.loadtxt(filterfn, unpack=True)
     self.p = pyproj.Proj(proj="aea", lat_0='0.00', lon_0='-120',
                          lat_1='34.00', lat_2='40.50',
                          ellps='GRS80', x_0=0.000, y_0=-4000000.000,
                          units='m', datum='NAD83')
     px, py = self.p(lon, lat)
     self.points = np.vstack((px, py)).T
     self.polygon = Polygon(zip(px, py))
     self.prepared_polygon = prep(self.polygon)
     self.lat1 = 31
     self.lat2 = 43
     self.lon1 = -126
     self.lon2 = -114
Пример #32
0
 def poly_count(self, poly_list, points):
     """
     counts how many agents in each polygon
     
     in: 
         1D vector of points from agents2state()/get_state(sensor=location),
     out: 
         counts of agents in each polygon in poly_list
     """
     counts = []
     points = np.array([points[::2], points[1::2]]).T
     points = MultiPoint(points)
     for poly in self.poly_list:
         poly = prep(poly)
         counts.append(int(len(list(filter(poly.contains, points)))))
     return counts
Пример #33
0
    def is_occupied(self, poly, auto_register=False):
        # prepare for multiple checking
        prepared = prep(poly)

        # filter hits
        hits = list(filter(prepared.intersects, self.occupied))

        # if we had no hits the area is not occupied
        if len(hits) == 0:
            if auto_register:
                # register box as occupied
                self.occupied.append(poly.buffer(20, resolution=1))
            return False

        # space is occupied
        return True
Пример #34
0
    def clip(self, polygon):
        ## perform an intersects operation first
        vd = self.intersects(polygon)
        ## prepare the geometry for intersection
        prep_igeom = prepared.prep(polygon)

        ## loop for the intersection
        geom = vd._geom
        for ii, jj in iter_array(geom):
            ref = geom[ii, jj]
            if not prep_igeom.contains(ref):
                new_geom = polygon.intersection(ref)
                geom[ii, jj] = new_geom

        ret = self.__class__(grid=vd.grid, geom=geom, uid=vd.uid)
        return (ret)
Пример #35
0
def get_country(lat, lon, geo_data):
    """
    Determine which country a point lies in
    """
    countries = {}
    for feature in geo_data["features"]:
        geom = feature["geometry"]
        country = feature["properties"]["ADMIN"]
        countries[country] = prep(shape(geom))

    point = Point(lon, lat)
    for country, geom in countries.items():
        if geom.contains(point):
            return country

    return "unknown"
Пример #36
0
    def tzNameAt(self, latitude, longitude, forceTZ=False):
        '''
        Let's you lookup for a given latitude and longitude the appropriate
        timezone.
        @latitude: latitude
        @longitude: longitude
        @forceTZ: If forceTZ is true and you can't find a valid timezone return
        the closest timezone you can find instead. Only works if the point has
        the same integer value for its degree than the timezeone
        '''

        if forceTZ:
            assert self.forceTZ, 'You need to initialize tzwhere with forceTZ'

        latTzOptions = self.timezoneLatitudeShortcuts[str(
            (math.floor(latitude / self.SHORTCUT_DEGREES_LATITUDE) *
             self.SHORTCUT_DEGREES_LATITUDE))]
        latSet = set(latTzOptions.keys())
        lngTzOptions = self.timezoneLongitudeShortcuts[str(
            (math.floor(longitude / self.SHORTCUT_DEGREES_LONGITUDE) *
             self.SHORTCUT_DEGREES_LONGITUDE))]
        lngSet = set(lngTzOptions.keys())
        possibleTimezones = lngSet.intersection(latSet)

        queryPoint = geometry.Point(longitude, latitude)

        if possibleTimezones:
            for tzname in possibleTimezones:
                if isinstance(self.timezoneNamesToPolygons[tzname],
                              COLLECTION_TYPE):
                    self.timezoneNamesToPolygons[tzname] = list(
                        map(
                            lambda p: prepared.prep(
                                geometry.Polygon(p[0], p[1])),
                            self.timezoneNamesToPolygons[tzname]))

                polyIndices = set(latTzOptions[tzname]).intersection(
                    set(lngTzOptions[tzname]))

                for polyIndex in polyIndices:
                    poly = self.timezoneNamesToPolygons[tzname][polyIndex]
                    if poly.contains_properly(queryPoint):
                        return tzname

        if forceTZ:
            return self.__forceTZ__(possibleTimezones, latTzOptions,
                                    lngTzOptions, queryPoint)
Пример #37
0
def _process_osm_trees_gardens(
        city_blocks: Set[CityBlock], parks: List[shg.Polygon],
        fg_elev: utilities.FGElev) -> Dict[e.TreeType, List[Tree]]:
    suburban_trees = list()
    town_trees = list()
    urban_trees = list()
    for city_block in city_blocks:
        tree_type = e.map_tree_type_from_settlement_type_garden(
            city_block.settlement_type)
        if city_block.type_ is e.BuildingZoneType.special_processing:
            continue
        prep_geom = prep(city_block.geometry)
        my_random_points = _generate_random_tree_points_in_polygon(
            city_block.geometry, prep_geom,
            parameters.C2P_TREES_DIST_BETWEEN_TREES_GARDEN,
            parameters.C2P_TREES_SKIP_RATE_TREES_GARDEN)

        for point in my_random_points:
            exclude = False
            for park in parks:  # need to check for parks
                if point.within(park):
                    exclude = True
                    break
            if exclude:
                continue
            if not _test_point_in_building(point, {city_block}, 2.0):
                elev = fg_elev.probe_elev((point.x, point.y), False)
                my_tree = Tree(
                    op.get_next_pseudo_osm_id(op.OSMFeatureType.generic_node),
                    point.x, point.y, elev)
                if tree_type is e.TreeType.suburban:
                    suburban_trees.append(my_tree)
                elif tree_type is e.TreeType.town:
                    town_trees.append(my_tree)
                else:
                    urban_trees.append(my_tree)

    garden_trees = dict()
    if suburban_trees:
        garden_trees[e.TreeType.suburban] = suburban_trees
    if town_trees:
        garden_trees[e.TreeType.town] = town_trees
    if urban_trees:
        garden_trees[e.TreeType.urban] = urban_trees
    logging.info('Number of trees added in gardens: %i',
                 len(suburban_trees) + len(town_trees) + len(urban_trees))
    return garden_trees
Пример #38
0
def maxMinDistance(poly, dd):
    allLines = []
    allLines.append(poly.exterior)
    postLayer = dd.layers[DesignDict.POST]
    portLayer = dd.layers[DesignDict.PORTS]
    possiblePosts = postLayer.index.intersection(poly.bounds)
    possiblePorts = portLayer.index.intersection(poly.bounds)
    candidatePosts = []
    prepPoly = prep(poly)
    construct = Polygon(poly)

    for objind in possiblePosts:
        obj = dd.objects[objind]
        if prepPoly.contains_properly(obj.shape):
            candidatePosts.append(obj.shape)

    for objind in possiblePorts:
        obj = dd.objects[objind]
        if prepPoly.contains_properly(obj.shape):
            candidatePosts.append(obj.shape)

    logger.debug(str(len(candidatePosts)) + " candidate support posts")

    for post in candidatePosts:
        ## subtract the post from the polygon interior
        construct = construct.difference(post)

    for interior in construct.interiors:
        candidatePosts.append(Polygon(interior))
        allLines.append(interior)

    allLines = MultiLineString(allLines)

    currentPoint = construct.centroid
    if construct.contains(currentPoint):
        currentDist = allLines.distance(currentPoint)
    else:
        currentDist = None

    triangles, pconstruct = prepPolygon(construct)
    points = nRandomTriangleSamples(pconstruct, triangles)
    for p in points:
        dist = allLines.distance(p)
        if dist > currentDist:
            currentPoint = p
            currentDist = dist
    return (currentPoint, currentDist)
Пример #39
0
def fndshapeindices(shapevertices=None):
    '''Define the gridpoints that lie within the 'shape' or on its boundary.
       These points will be included in the sum of emissivities.

       Kwargs:

        shapevertices (list) : list of vertex coordinates for trial shape ("shape").

       Returns:

        pCoords (list): coordinates of grid points within or on boundary of shape.
       '''
    polygon = Polygon(shapevertices)
    prepared_polygon = prep(polygon)
    bounds = polygon.bounds
    ll = bounds[:2]
    ur = bounds[2:]
    xs = []
    ys = []

    if (ur[0] - ll[0] < 1) or (ur[1] - ll[1] < 1):
        return None

    xx = range(int(np.ceil(ll[0])), int(np.floor(ur[0])) + 1, 1)
    yy = range(int(np.ceil(ll[1])), int(np.floor(ur[1])) + 1, 1)

    listpoints = list(itertools.product(xx, yy))
    points = MultiPoint(listpoints)

    try:
        xvals, yvals = zip(*listpoints)
    except:
        print('ll', ll, 'ur', ur)
        print('vertices', shapevertices)
        print('xx', xx, 'yy', yy)

    for ii in range(len(xvals)):
        if prepared_polygon.intersects(points[ii]):
            xs.append(xvals[ii])
            ys.append(yvals[ii])
    ##plot to check
    #x,y = polygon.exterior.xy
    #plt.plot(x,y)
    #plt.show()
    pCoords = [xs], [ys]
    return pCoords
Пример #40
0
    def _split_polygon_with_line(poly, splitter):
        """Split a Polygon with a LineString"""

        assert(isinstance(poly, Polygon))
        assert(isinstance(splitter, LineString))

        union = poly.boundary.union(splitter)

        # greatly improves split performance for big geometries with many
        # holes (the following contains checks) with minimal overhead
        # for common cases
        poly = prep(poly)

        # some polygonized geometries may be holes, we do not want them
        # that's why we test if the original polygon (poly) contains
        # an inner point of polygonized geometry (pg)
        return [pg for pg in polygonize(union) if poly.contains(pg.representative_point())]
def get_watershed(dataframe,
                  shapefile=None,
                  location_id=None,
                  lat=None,
                  lon=None,
                  singluar_removal=False):
    '''
    add a column with watershed information
    Args:
        dataframe: pandas dataframe
        shapefile (string, dir to an shp file): shape information of watersheds
        location_id (string): the name of column of location names/ids
        lat (string): the name of the column of latitude information
        lon (string): the name of the column of longitude information
        singular_removal: boolean if true the isolated locations wille be removed.
    '''
    shapefile = WATERSHED_PATH if shapefile is None else shapefile
    location_id = 'SITENUMBER' if location_id is None else location_id
    lat = 'LATITUDE' if lat is None else lat
    lon = 'LONGITUDE' if lon is None else lon

    lats_and_lons = dataframe.groupby(location_id).first()[[lat, lon
                                                            ]].reset_index()

    shapes = []
    names = []
    for i in fiona.open(shapefile):
        names.append(i['properties']['NAME'])
        shapes.append(prep(shape(i['geometry'])))

    dict_ = {}
    for idx, row in lats_and_lons.iterrows():
        sitenumber, lat, lon = row.values
        point = Point([lon, lat])
        for watershed_name, shape_ in zip(names, shapes):
            if shape_.contains(point):
                dict_[sitenumber] = watershed_name
                break

    dataframe['WATERSHED'] = dataframe[location_id].map(dict_)
    if singluar_removal:
        number_of_obs = dataframe.groupby(['WATERSHED']).count()[key]
        singular_huc_areas = number_of_obs[number_of_obs <= 1].index
        dataframe = dataframe[~dataframe.WATERSHED.isin(singular_huc_areas)]

    return dataframe
Пример #42
0
    def get_neighbors_within_distance(
        self, agent, distance, center=False, relation="intersects"
    ):
        """Return a list of agents within `distance` of `agent`.

        Distance is measured as a buffer around the agent's shape,
        set center=True to calculate distance from center.
        """
        if center:
            shape = agent.shape.center().buffer(distance)
        else:
            shape = agent.shape.buffer(distance)
        possible_neighbors = self._get_rtree_intersections(shape)
        prepared_shape = prep(shape)
        for other_agent in possible_neighbors:
            if getattr(prepared_shape, relation)(other_agent.shape):
                yield other_agent
Пример #43
0
def _get_ocean_shapefile():
    """ Load the ocean basins shapefile. """

    global _OCEAN_SHAPE

    if _OCEAN_SHAPE is None:
        try:
            ocean_shp_fn = pkg_resources.resource_filename(
                "marc_analysis", "data/ne_110m_ocean.shp")
            _OCEAN_SHAPE = geopandas.read_file(ocean_shp_fn)
            _OCEAN_SHAPE = MultiPolygon(_OCEAN_SHAPE.geometry.values.tolist())
            _OCEAN_SHAPE = prep(_OCEAN_SHAPE)
        except OSError:
            warnings.warn("Unable to locate oceans shapefile; ocean"
                          " point mask is not available")

    return _OCEAN_SHAPE
Пример #44
0
 def makeMouseBites(self, cuts, diameter, spacing, offset=fromMm(0.25)):
     """
     Take a list of cuts and perform mouse bites.
     """
     bloatedSubstrate = prep(self.boardSubstrate.substrates.buffer(fromMm(0.01)))
     for cut in cuts:
         cut = cut.simplify(fromMm(0.001)) # Remove self-intersecting geometry
         offsetCut = cut.parallel_offset(offset, "left")
         length = offsetCut.length
         count = int(length / spacing) + 1
         for i in range(count):
             if count == 1:
                 hole = offsetCut.interpolate(0.5, normalized=True)
             else:
                 hole = offsetCut.interpolate( i * length / (count - 1) )
             if bloatedSubstrate.intersects(hole.buffer(0.8 * diameter / 2)):
                 self.addNPTHole(wxPoint(hole.x, hole.y), diameter)
Пример #45
0
def create_grid(site_shape: BaseGeometry,
                center: Point,
                grid_angle: float,
                intrarow_spacing: float,
                interrow_spacing: float,
                row_phase_offset: float,
                max_sites: int = None,
                ) -> [Point]:
    """
    Get a list of coordinates placed along a grid inside a site boundary
    :param site_shape: Polygon
    :param center: where to center the grid
    :param grid_angle: in degrees where 0 is north, increasing clockwise
    :param intrarow_spacing: distance between turbines along same row
    :param interrow_spacing: distance between rows
    :param row_phase_offset: offset of turbines along row from one row to the next
    :param max_sites: max number of turbines
    :return: list of coordinates
    """
    grid_lines: [LineString] = make_grid_lines(
        site_shape,
        center,
        grid_angle,
        interrow_spacing
        )
    phase_offset: float = row_phase_offset * intrarow_spacing
    
    prepared_site = prep(site_shape)
    grid_positions: [Point] = []
    for row_number, grid_line in enumerate(grid_lines):
        length = grid_line.length
        
        # generate points along that line with the right phase offset
        x: float = (phase_offset * row_number) % intrarow_spacing
        while x <= length:
            position = grid_line.interpolate(x)
            if prepared_site.contains(position):
                if max_sites and len(grid_positions) >= max_sites:
                    break
                grid_positions.append(position)
            x += intrarow_spacing
        if max_sites and len(grid_positions) >= max_sites:
            break
    
    return grid_positions
Пример #46
0
def remove_duplicates(layer):

    indices = []
    for i in range(0, len(layer)):
        obj_prep = prep(layer[i])
        for j in range(i + 1, len(layer)):
            obj_comp = layer[j]

            if j in indices:
                continue

            if obj_prep.contains(obj_comp):
                indices.append(j)

    for i in sorted(indices, reverse=True):
        del layer[i]

    return len(indices)
Пример #47
0
    def clip(self,igeom):
        ## logic for convenience. just return the provided collection if a NoneType
        ## is passed for the 'igeom' arugment
        if igeom is not None:
            ## take advange of shapely speedups
            prep_igeom = prepared.prep(igeom)
            ## the weight array
            weights = np.zeros(self.spatial.shape,dtype=float)
            weights = np.ma.array(weights,mask=self.spatial._value_mask)
            ## do the spatial operation
            for idx,geom in iter_array(self.spatial.value,return_value=True):
                if not prep_igeom.contains(geom):
#                if keep(prep_igeom,igeom,geom):
                    new_geom = igeom.intersection(geom)
                    weights[idx] = new_geom.area
                    self.spatial._value[idx] = new_geom
            ## set maximum weight to one
            self.spatial.weights = weights/np.ma.max(weights)
Пример #48
0
def is_land(x, y, res="110m"):

    if 'prep' not in globals():
        raise ImportError("cartopy is needed to design ocean-only source.")
    assert (res in ["10m", "50m",
                    "110m"]), "Resolution must be 10m, 50m, 110 m"

    land_shp_fname = shpreader.natural_earth(resolution=res,
                                             category='physical',
                                             name='land')

    land_geom = unary_union(list(
        shpreader.Reader(land_shp_fname).geometries()))
    land = prep(land_geom)
    is_land = np.zeros(len(x))
    for i in range(len(x)):
        is_land[i] = land.contains(sgeom.Point(x[i], y[i]))
    return is_land
Пример #49
0
    def find_pages_for_polygon(self, polygon):
        """Find pages within polygon using repeated Geosearch

        The Geosearch API has no polygon support; only point. To get around
        this, I first find a collection of circles that together tile the
        polygon, then for each circle I call the geosearch API.
        """
        # When set to radius=10000, I got an error from the wikipedia API
        points, radii = geom.find_circles_that_tile_polygon(
            polygon, radius=10000)

        titles = set()
        for point, radius in zip(points, radii):
            radius = math.ceil(radius)
            res = self.find_page_titles_around_point(point=point, radius=radius)
            titles.update(res)

        # Get wikipedia page metadata for each of the titles I've found above
        # Occasionally you get a disambiguation error, because the search is by
        # title?
        # Note, since I've already found titles that I know exist, I should set
        # auto_suggest=False
        pages = []
        for title in titles:
            try:
                pages.append(wikipedia.page(title, auto_suggest=False))
            except wikipedia.WikipediaException:
                pass

        # Make sure that all returned articles are within the original polygon
        # [::-1] because returned as lat, lon. Point requires lon, lat
        # "To test one polygon containment against a large batch of points, one
        # should first use the prepared.prep() function"
        prepared_polygon = prep(polygon)
        new_pages = []
        for page in pages:
            try:
                if prepared_polygon.contains(Point(page.coordinates[::-1])):
                    new_pages.append(page)
            # Occasionally the page won't have a coordinates attribute
            except KeyError:
                pass

        return new_pages
Пример #50
0
def add_boundary_perimeters(graph, geometries):
    """Add shared perimeter between nodes and the total geometry boundary.

    :param graph: NetworkX graph
    :param df: Geodataframe containing geometry information.
    :return: The updated graph.
    """
    prepared_boundary = prep(unary_union(geometries).boundary)

    boundary_nodes = geometries.boundary.apply(prepared_boundary.intersects)

    for node in graph:
        graph.nodes[node]["boundary_node"] = bool(boundary_nodes[node])
        if boundary_nodes[node]:
            total_perimeter = geometries[node].boundary.length
            shared_perimeter = sum(neighbor_data["shared_perim"]
                                   for neighbor_data in graph[node].values())
            boundary_perimeter = total_perimeter - shared_perimeter
            graph.nodes[node]["boundary_perim"] = boundary_perimeter
Пример #51
0
    def is_in_grid(self, shp):
        """Check if arbitrary polygon is within grid bounding box.

        Args:
            shp (shape):
        Returns:
            Bool whether shp is in grid box.

        Depends on self.grid_box (shapely prep type) being defined
        in environment.
        """
        if not hasattr(shp, 'geom_type'):
            raise Exception("CoreMSR [is_in_grid] : invalid shp given")

        if not isinstance(self.grid_box, type(prep(Point(0, 0)))):
            raise Exception("CoreMSR [is_in_grid] : invalid prep_adm0 "
                            "found")

        return self.grid_box.contains(shp)
Пример #52
0
    def edge_intersects_other_restricted_areas(
            self, line: LineString, restricted_area_poly: Polygon) -> bool:
        """
        check if a linestring intersects with other as restricted marked polygons which are different from the given restricted_Area_poly

        :param line: the linestring which shall be checked
        :param restricted_area_poly: the polygon which shall be excluded
        :return: true if the linstring don't intesect other restricted polygon and touches the given polygon
        """
        other_restricted_areas = self._get_other_restricted_area_polys(
            restricted_area_poly)
        for other_restricted_area in other_restricted_areas:
            other_areas = self._get_other_restricted_area_polys(
                other_restricted_area)
            other_areas.remove(restricted_area_poly)
            if prep(other_restricted_area).touches(
                    line) and not self._is_restricted_line(line, other_areas):
                return False
        return self._is_restricted_line(line, other_restricted_areas)
Пример #53
0
 def revmatches():
     for row, shp in izip(
             subdict["refdata"].reader.iterRecords(),
             subdict["refdata"].reader.iterShapes()):
         #if dict(zip(self.fields, row))["SOV0NAME"] != "Russia": continue
         #print "...",row[1] #row[4],row[14]
         print str(row)[:100]
         prepped = prep(
             asShape(shp)
         )  # prepares geometry for many intersection tests (maybe only useful if is polygon and other is points, but not sure)
         bbox = [
             shp.points[0][0], shp.points[0][1],
             shp.points[0][0], shp.points[0][1]
         ] if shp.shapeType == pyshp.POINT else shp.bbox
         ilist = self.spindex.intersection(bbox)
         for i in ilist:
             othershp = self.reader.shape(i)
             if prepped.intersects(asShape(othershp)):
                 yield row, i
Пример #54
0
    def filter(self, intersects):
        """Filter results that intersect a given GeoFeature or Vector.

        """
        try:
            crs = self.crs
            vector = intersects.geometry if isinstance(intersects, GeoFeature) else intersects
            prepared_shape = prep(vector.get_shape(crs))
            hits = []

            for feature in self:
                target_shape = feature.geometry.get_shape(crs)
                if prepared_shape.overlaps(target_shape) or prepared_shape.intersects(target_shape):
                    hits.append(feature)

        except IndexError:
            hits = []

        return FeatureCollection(hits)
Пример #55
0
def prepare_earth_geometry(geometry_resolution: str = "50m"):
    """
    Preparations necessary for determining whether a point is over land or water.
    This code may need to download a ZIP containing Earth geometry data the first time it runs.
    Code borrowed from   https://stackoverflow.com/a/48062502
    :param geometry_resolution: The resolution of the NaturalEarth shapereader to use.  Valid values are '10m', '50m'
    or '110m'.  Default '50m'.
    :return: The PreparedGeometry object that can be used for point-land checking.
    :raises ValueError: If geometry_resolution is not '10m', '50m', or '110m'.
    """
    if geometry_resolution not in ["10m", "50m", "110m"]:
        raise ValueError("Argument 'geometry_resolution' must be either '10m', '50m', or '110m'.")

    print("--  Preparing Earth geometry...")
    land_shp_fname = shpreader.natural_earth(resolution=geometry_resolution, category='physical', name='land')
    land_geom = unary_union(list(shpreader.Reader(land_shp_fname).geometries()))
    land = prep(land_geom)
    print("--  Earth geometry prepared.")
    return land
Пример #56
0
def surround_with_holes(geometry, hole_spacing, hole_radius, padding, max_distance):
    """
    Surrounds the given geometry with holes, which are arranged in a square lattice around the structure.
    This can be used for generating vortex traps like presented in https://doi.org/10.1103/PhysRevApplied.11.064053

    :param geometry: The geometry around which the holes are generated
    :param hole_spacing: Spacing between the holes
    :param hole_radius: Radius of the holes
    :param padding: Padding around the geometry
    :param max_distance: Maximum distance of a hole from the geometry
    :return: Shapely object, which describes the holes
    """
    geometry = geometric_union(geometry if isinstance(geometry, (tuple, list)) else (geometry,))
    buffer_around_waveguide = geometry.buffer(max_distance)
    area_for_holes = prep(buffer_around_waveguide.difference(geometry.buffer(hole_radius + padding)))
    area = buffer_around_waveguide.bounds
    points = (Point(x, y) for x in np.arange(area[0], area[2], hole_spacing) for y in
              np.arange(area[1], area[3], hole_spacing))
    return MultiPolygon([point.buffer(hole_radius) for point in points if area_for_holes.contains(point)])
Пример #57
0
def prepare(feat):
    """Prepare geojson feature for further processing in `geopip._shapely.p_in_polygon()`

    Parameters:
        feat: Dict[str, Any]  Geojson feature (only Polygon and MultiPolygon will
                              be processed).

    Returns:
        List[Dict[str, Any]]  Prepared shapes for `geopip._shapely.p_in_polygon()`
    """
    if feat['geometry']['type'] in ('Polygon', 'MultiPolygon'):
        shp = shape(feat['geometry'])
        return [{
            'shape': prep(shp),
            'properties': feat['properties'],
            'bounds': shp.bounds,
        }]
    else:
        return []
def minDistInLayer(rule, dd, layerID, thresh):
    layer = dd.layers[layerID]
    objs = layer.objs
    for id1, o1 in objs.items():
        bbox = o1.shape.buffer(thresh).bounds
        candidates = layer.index.intersection(bbox)
        prepared = None
        for cind in candidates:
            o2 = objs[cind]
            if o1.id < o2.id:
                if prepared == None:
                    prepared = prep(o1.shape)
                contained = prepared.contains(o2.shape) or \
                            o2.shape.contains(o1.shape)

                if not contained and checkThresh(o1, o2, thresh):
                    (p1, p2) = NearLineSegment.featureToFeature(o1, o2)
                    wit = Witness(Witness.LINE_SEGMENT, (p1, p2))
                    dd.violations.add(Violation.ofRule(rule, [o1, o2], [wit]))
Пример #59
0
def geometryvariable_get_mask_from_intersects(
        gvar,
        geometry,
        use_spatial_index=env.USE_SPATIAL_INDEX,
        keep_touches=False,
        original_mask=None):
    # Create the fill array and reference the mask. This is the output geometry value array.
    if original_mask is None:
        original_mask = gvar.get_mask(create=True)
    fill = original_mask.copy()
    fill.fill(True)
    ref_fill_mask = fill.reshape(-1)

    # Track global indices because spatial operations only occur on non-masked values.
    global_index = np.arange(original_mask.size)
    global_index = np.ma.array(global_index, mask=original_mask).compressed()
    # Select the geometry targets. If an original mask is provided, use this. It may be modified to limit the search
    # area for intersects operations. Useful for speeding up grid subsetting operations.
    geometry_target = np.ma.array(gvar.get_value(),
                                  mask=original_mask).compressed()

    if use_spatial_index:
        si = gvar.get_spatial_index(target=geometry_target)
        # Return the indices of the geometries intersecting the target geometry, and update the mask accordingly.
        for idx in si.iter_intersects(geometry,
                                      geometry_target,
                                      keep_touches=keep_touches):
            ref_fill_mask[global_index[idx]] = False
    else:
        # Prepare the polygon for faster spatial operations.
        prepared = prep(geometry)
        # We are not keeping touches at this point. Remember the mask is an inverse.
        for idx, geom in iter_array(geometry_target, return_value=True):
            bool_value = False
            if prepared.intersects(geom):
                if not keep_touches and geometry.touches(geom):
                    bool_value = True
            else:
                bool_value = True
            ref_fill_mask[global_index[idx]] = bool_value

    return fill
Пример #60
0
def Filter(options):
    '''
	Rounding
	http://gis.stackexchange.com/questions/8650/how-to-measure-the-accuracy-of-latitude-and-longitude
	'''
    startTime = time.time()
    inputData = np.loadtxt(options.inputFileName,
                           delimiter=',',
                           usecols=(0, 1, 2))
    outputData = open(options.outputFileName, 'w')

    lon = inputData[:, 0]
    lat = inputData[:, 1]
    height = inputData[:, 2]

    if options.polyFilter != False:
        poly = np.loadtxt(options.polyFilter, delimiter=',', usecols=(1, 2))
        poly = Polygon(poly)
        poly = prep(poly)

    minHeight = float(options.minHeight)
    maxHeight = float(options.maxHeight)
    numPoints = inputData.shape[0]

    for i in range(0, numPoints):
        pointLon, pointLat, pointHeight = lon[i], lat[i], height[i]
        if minHeight < pointHeight < maxHeight:
            if options.polyFilter != False:
                point = Point(pointLon, pointLat)
                if poly.contains(point):
                    outputData.write(
                        str(round(pointLon, 8)) + ',' +
                        str(round(pointLat, 8)) + ',' +
                        str(round(pointHeight, 4)) + '\n')
            else:
                outputData.write(
                    str(round(pointLon, 8)) + ',' + str(round(pointLat, 8)) +
                    ',' + str(round(pointHeight, 4)) + '\n')
    outputData.close()

    #Use np.savetxt('test.out', x, delimiter=',')
    print(int(time.time() - startTime), ' seconds runtime')