Example #1
0
def doPolygonize():
  blocks = polygonize(lines)
  writeBlocks(blocks, args[0] + '-blocks.geojson')

  blocks = polygonize(lines)
  bounds = Polygon([
    [minlng, minlat],
    [minlng, maxlat],
    [maxlng, maxlat],
    [maxlng, minlat],
    [minlng, minlat]
  ])
  # Geometry transform function based on pyproj.transform
  project = partial(
    pyproj.transform,
    pyproj.Proj(init='EPSG:3785'),
    pyproj.Proj(init='EPSG:4326'))
  print bounds
  print transform(project, bounds)

  print 'finding holes'
  for index, block in enumerate(blocks):
    if index % 1000 == 0:
      print "diff'd  %s" % (index)
    if not block.is_valid:
      print explain_validity(block)
      print transform(project, block)
    else:
      bounds = bounds.difference(block)
  print bounds
Example #2
0
def roundAndRemoveInvalidPoints(polygon):
    coords = [(x, y) for x, y in polygon.exterior.coords]
    coords = [(round(x, 8), round(y, 8)) for x, y in coords]
    retPoly = Polygon(coords)
    if retPoly.is_valid:
        return retPoly
    explanation = explain_validity(retPoly)
    match = re.match('Self-intersection\[(?P<first>-?\d+\.\d+) (?P<sec>-?\d+\.\d+)\]', explanation)
    if not match:
        print(explain_validity(retPoly))
        assert False

    errorx, errory = float(match.group(1)), float(match.group(2))
    closestD = inf
    closestP = None
    for px, py in retPoly.exterior.coords:
        d = (px - errorx) ** 2 + (py - errory) ** 2
        if d < closestD:
            closestD = d
            closestP = (px, py)
    retPoly = Polygon([(x, y) for x, y in list(retPoly.exterior.coords) if (x, y) != closestP])
    if retPoly.is_valid:
        return retPoly
    print(explain_validity(retPoly))
    assert False
def overlapping_entity_pairs(entity_set1_overlaid, entity_set2_overlaid):
    entity_set1_overlaid = gpd.GeoDataFrame(
        pd.concat(entity_set1_overlaid, ignore_index=True))
    entity_set2_overlaid = gpd.GeoDataFrame(
        pd.concat(entity_set2_overlaid, ignore_index=True))
    all_vertices1 = []
    all_vertices2 = []

    # Obtain vertices of all entities to be matched.
    for index, row in entity_set1_overlaid.iterrows():
        if row.geometry.geom_type == 'Polygon':
            all_vertices1.append(list(row.geometry.exterior.coords))
        else:
            all_vertices1.append(list(row.geometry.coords))
    all_vertices1 = MultiPoint(sum(all_vertices1, []))

    for index, row in entity_set2_overlaid.iterrows():
        if row.geometry.geom_type == 'Polygon':
            all_vertices2.append(list(row.geometry.exterior.coords))
        else:
            all_vertices2.append(list(row.geometry.coords))
    all_vertices2 = MultiPoint(sum(all_vertices2, []))

    # Compute overlapping area by computing the intersection area of convex_hulls which are generated with all vertices.
    all_vertices1_convexhull = all_vertices1.convex_hull
    all_vertices2_convexhull = all_vertices2.convex_hull
    overlapping_area = all_vertices1_convexhull.intersection(
        all_vertices2_convexhull)
    links_gdf = gpd.GeoDataFrame(geometry=[overlapping_area])
    links_gdf.to_file("intersection.shp")

    # Those entities which do not intersect with the overlapping area will be removed.
    entity_set1_overlaid_copy = entity_set1_overlaid.copy()
    for index, row in entity_set1_overlaid.iterrows():
        if explain_validity(row.geometry) == 'Valid Geometry':
            if row.geometry.intersect(overlapping_area).is_empty:
                delete_index = entity_set1_overlaid_copy[
                    entity_set1_overlaid_copy['FeaID'] ==
                    row.FeaID].index.tolist()
                entity_set1_overlaid_copy.drop(
                    entity_set1_overlaid_copy.index[delete_index],
                    inplace=True)
                entity_set1_overlaid_copy.index = range(
                    len(entity_set1_overlaid_copy))

    entity_set2_overlaid_copy = entity_set2_overlaid.copy()
    for index, row in entity_set2_overlaid.iterrows():
        if explain_validity(row.geometry) == 'Valid Geometry':
            if row.geometry.intersect(overlapping_area).is_empty:
                delete_index = entity_set2_overlaid_copy[
                    entity_set2_overlaid_copy['FeaID'] ==
                    row.FeaID].index.tolist()
                entity_set2_overlaid_copy.drop(
                    entity_set2_overlaid_copy.index[delete_index],
                    inplace=True)
                entity_set2_overlaid_copy.index = range(
                    len(entity_set2_overlaid_copy))

    return entity_set1_overlaid_copy, entity_set2_overlaid_copy
Example #4
0
def atr_within(row, radius):
    geometry_sou = row['sou_feature']
    geometry_tar = row['tar_feature']
    buf_1 = geometry_sou.buffer(radius)
    buf_2 = geometry_tar.buffer(radius)

    if explain_validity(geometry_sou) == 'Valid Geometry' and explain_validity(geometry_tar) == 'Valid Geometry':
        area = buf_1.intersection(buf_2).area
        area_ratio = area/(min(buf_1.area, buf_2.area))
        return area_ratio
Example #5
0
def FixAntiMeridianPolygon(ls):
    """Detects and fix a 180deg crossing polygon.

  Args:
    ls: a linestring as a list of 'lon,lat,alt' strings.

  Returns:
    None if not a anti-meridian polygon otherwise the western part linestring.

  Side effects:
    If detected anti-meridian, the given linestring is modified to be the easter
    part.
  """
    coords = []
    found_anti_meridian = False
    for c in ls:
        xy = c.split(',')
        coords.append([float(xy[0]), float(xy[1])])
        if float(xy[0]) == 180:
            found_anti_meridian = True
    lr = LinearRing(coords)
    polygon = Polygon(lr)
    # The invalid polygon is the case of Semisopochnoi Island, which
    # zone crosses the antimeridian.
    if not polygon.is_valid:
        print 'POLYGON IS NOT VALID! : %d' % len(ls)
        explain_validity(polygon)
        if found_anti_meridian:
            print 'Polygon spans anti-meridian - Splitting in 2'
            # To deal with this case, we'll split the zone into two pieces,
            # one of which is in the eastern hemisphere and one in the
            # western hemisphere. This is purely a tooling issue to make
            # the zone easier to manage with other software.
            new_piece = []
            begin_anti_meridian = -1
            end_anti_meridian = -1
            for i in range(0, len(ls)):
                xy = ls[i].split(',')
                if float(xy[0]) == 180:
                    # Note: the '-' is to reverse the sign so shapely sees
                    # the coordinates correctly.
                    new_piece.append('-' + ls[i])
                    if begin_anti_meridian == -1:
                        begin_anti_meridian = i
                    else:
                        end_anti_meridian = i
                        new_piece.append(new_piece[0])
                elif begin_anti_meridian >= 0 and end_anti_meridian == -1:
                    new_piece.append(ls[i])

            del ls[begin_anti_meridian + 1:end_anti_meridian]
            return new_piece
    return None
Example #6
0
def fix_poly(plist):
    print "  " + str(len(plist))
    try:
        shape = Polygon(plist)
    except ValueError:
        return []

    validity = explain_validity(shape)
    if validity == "Valid Geometry":
        return [shape]

    shape_list = []
    while plist != []:
        #print "  " + str(len(plist))
        longest_valid = 0
        best_choice = None
        for i in range(len(plist)):
            # it might be that no matter how long the longest valid polygon is from this point, it can't
            # beat the current max, if so, just break
            if (len(plist) - i) < longest_valid:
                break

            longest_valid_i = 0
            best_choice_i = None
            for j in range(i + 1, len(plist)):
                try:
                    temp_shape = Polygon(plist[i:j])
                    validity = explain_validity(temp_shape)

                    if (validity == "Valid Geometry") and (
                        (j - i) > longest_valid_i):
                        longest_valid_i = j - i
                        best_choice_i = i, j
                except ValueError:
                    continue
            if longest_valid_i > longest_valid:
                longest_valid = longest_valid_i
                best_choice = best_choice_i
        if best_choice is None:
            break

        i, j = best_choice
        shape = Polygon(plist[i:j])
        shape_list.append(shape)
        test_validity = explain_validity(shape)
        assert test_validity == "Valid Geometry"

        plist_temp = plist[:i]
        plist_temp.extend(plist[j:])
        plist = plist_temp
    return shape_list
Example #7
0
def fix_poly(plist):
    print "  " + str(len(plist))
    try:
        shape = Polygon(plist)
    except ValueError:
        return []

    validity = explain_validity(shape)
    if validity == "Valid Geometry":
        return [shape]

    shape_list = []
    while plist != []:
        #print "  " + str(len(plist))
        longest_valid = 0
        best_choice = None
        for i in range(len(plist)):
            # it might be that no matter how long the longest valid polygon is from this point, it can't
            # beat the current max, if so, just break
            if (len(plist)-i) < longest_valid:
                break

            longest_valid_i = 0
            best_choice_i = None
            for j in range(i+1,len(plist)):
                try:
                    temp_shape = Polygon(plist[i:j])
                    validity = explain_validity(temp_shape)

                    if (validity == "Valid Geometry") and ((j-i) > longest_valid_i):
                        longest_valid_i = j-i
                        best_choice_i = i,j
                except ValueError:
                    continue
            if longest_valid_i > longest_valid:
                longest_valid = longest_valid_i
                best_choice = best_choice_i
        if best_choice is None:
            break

        i,j = best_choice
        shape = Polygon(plist[i:j])
        shape_list.append(shape)
        test_validity = explain_validity(shape)
        assert test_validity == "Valid Geometry"

        plist_temp = plist[:i]
        plist_temp.extend(plist[j:])
        plist = plist_temp
    return shape_list
def minkowski_sum_2(poly1, poly2):
    ''' Slower minkowski sum algorithm (convex hull operation is a lot slower), but 
    uses blazing fast numpy sums and doesn't require particular polygon orientation'''
    
    assert poly1.is_valid, validation.explain_validity(poly1)
    assert poly2.is_valid, validation.explain_validity(poly2)

    ext1 = np.array(poly1.boundary)[:-1,:]
    ext2 = np.array(poly2.boundary)[:-1,:]
    n_ext2 = ext2.shape[0]    
    n_ext1 = ext1.shape[0]
    
    ext_sum = np.repeat(ext1, n_ext2, axis=0) + np.tile(ext2, (n_ext1, 1))    
    
    return geom.asPolygon(ext_sum).convex_hull
Example #9
0
def _get_reprojected_features(input_file=None,
                              dst_bounds=None,
                              dst_crs=None,
                              validity_check=False):
    with fiona.open(input_file, 'r') as vector:
        vector_crs = CRS(vector.crs)
        # Reproject tile bounding box to source file CRS for filter:
        if vector_crs == dst_crs:
            dst_bbox = box(*dst_bounds)
        else:
            dst_bbox = reproject_geometry(box(*dst_bounds),
                                          src_crs=dst_crs,
                                          dst_crs=vector_crs,
                                          validity_check=True)
        for feature in vector.filter(bbox=dst_bbox.bounds):
            feature_geom = to_shape(feature['geometry'])
            if not feature_geom.is_valid:
                feature_geom = feature_geom.buffer(0)
                # skip feature if geometry cannot be repaired
                if not feature_geom.is_valid:
                    logger.exception("feature omitted: %s",
                                     explain_validity(feature_geom))
                    continue
            # only return feature if geometry type stayed the same after
            # reprojecction
            geom = clean_geometry_type(feature_geom.intersection(dst_bbox),
                                       feature_geom.geom_type)
            if geom:
                # Reproject each feature to tile CRS
                try:
                    geom = reproject_geometry(geom,
                                              src_crs=vector_crs,
                                              dst_crs=dst_crs,
                                              validity_check=validity_check)
                    if validity_check and not geom.is_valid:
                        raise TopologicalError(
                            "reprojected geometry invalid: %s" %
                            (explain_validity(geom)))
                except TopologicalError:
                    logger.exception("feature omitted: reprojection failed")
                yield {
                    'properties': feature['properties'],
                    'geometry': mapping(geom)
                }
            else:
                logger.exception(
                    "feature omitted: geometry type changed after reprojection"
                )
Example #10
0
 def check_valid_shape(self, shape):
     if not shape.is_valid:
         validity = explain_validity(shape)
         print("Shape is not valid. Explanation: %s", validity)
         return False
     else:
         return True
Example #11
0
    def toPolygon(self, tileXy,imgPath):


        img = Image.open(imgPath)#打开图片
        newImg = Image.new("RGBA",(260,260),(255,255,255))
        newImg.paste(img,(2,2))
        newImg.save(imgPath)

        img = io.imread(imgPath)
        img = color.rgb2gray(img)  # 检测所有图形的轮廓
        contours = measure.find_contours(img, 0.8)  # 绘制轮廓

        polygonList = []
        for n, contour in enumerate(contours):
            pointList = []
            for xy in contour:
                pointList.append(self.pixelToLonlat(tileXy,xy[1]-2, xy[0]-2))
            if len(pointList) <4:
                continue
            p = Polygon(pointList)
            if not p.is_valid:
                p = p.buffer(0)
                assert p.is_valid, \
                    "Contour %r did not make valid polygon %s because %s" \
                    % (p, p.wkt, explain_validity(p))
            polygonList.append(p)
        return polygonList
Example #12
0
    def shape(self):
        # shapely's idea of "holes" are to subtract everything in the second set
        # from the first. So let's at least make sure the "first" thing is the
        # biggest path.
        paths = self.paths
        paths.sort(key=lambda point_list: shgeo.Polygon(point_list).area,
                   reverse=True)
        # Very small holes will cause a shape to be rendered as an outline only
        # they are too small to be rendered and only confuse the auto_fill algorithm.
        # So let's ignore them
        if shgeo.Polygon(paths[0]).area > 5 and shgeo.Polygon(
                paths[-1]).area < 5:
            paths = [path for path in paths if shgeo.Polygon(path).area > 3]

        polygon = shgeo.MultiPolygon([(paths[0], paths[1:])])

        # There is a great number of "crossing border" errors on fill shapes
        # If the polygon fails, we can try to run buffer(0) on the polygon in the
        # hope it will fix at least some of them
        if not self.shape_is_valid(polygon):
            why = explain_validity(polygon)
            message = re.match(r".+?(?=\[)", why)
            if message.group(0) == "Self-intersection":
                buffered = polygon.buffer(0)
                # if we receive a multipolygon, only use the first one of it
                if type(buffered) == shgeo.MultiPolygon:
                    buffered = buffered[0]
                # we do not want to break apart into multiple objects (possibly in the future?!)
                # best way to distinguish the resulting polygon is to compare the area size of the two
                # and make sure users will not experience significantly altered shapes without a warning
                if type(buffered) == shgeo.Polygon and math.isclose(
                        polygon.area, buffered.area, abs_tol=0.5):
                    polygon = shgeo.MultiPolygon([buffered])

        return polygon
Example #13
0
def pts2feature(pts, nom):
    poly = []
    km = None
    for pt in pts:
        lon = dms2d(pt[1], pt[2], pt[3], pt[4])
        lat = dms2d(pt[5], pt[6], pt[7], pt[8])
        poly.append((lon, lat))
        km = pt[9]
    if km:
        # calcule un cercle en projection Lambert 93
        zone_local = ops.transform(
            partial(
                pyproj.transform,
                pyproj.Proj(init='EPSG:4326'),  # EPSG:4326 est WGS 84
                pyproj.Proj(init='EPSG:2154')),
            Point(poly[0])).buffer(float(km.replace(',', '.')) * 1000,
                                   resolution=36)
        zone = ops.transform(
            partial(
                pyproj.transform,
                pyproj.Proj(init='EPSG:2154'),
                pyproj.Proj(init='EPSG:4326')  # EPSG:4326 est WGS 84
            ),
            zone_local)
        return (Feature(zone, {'nom': nom, 'distance': km}))
    else:
        valid = explain_validity(Polygon(poly))
        if valid != 'Valid Geometry':
            print('ERREUR:', nom, valid)
            exit()
        if Polygon(poly).area > 0.01 and nom not in ['CSG KOUROU 1']:
            print('ERREUR:', nom, 'emprise trop importante')
            exit()
        return (Feature(Polygon(poly), {'nom': nom}))
Example #14
0
    def _LoadPolygons(self):
        with Shapely2ESRI(self.ShapefilePath) as reader:

            polygons = []
            self.TRACKER.startProcess(len(reader))
            for polygon in reader.readThrough():
                fid = polygon['FID']

                if not polygon.is_valid:
                    raise Exception("The polygon at FID=%s is not valid: %s" %
                                    (fid, explain_validity(polygon)))

                try:
                    val = polygon[self.ShapefileFieldIdToLoad]
                    polygon[self.ShapefileFieldIdToLoad] = float(val)
                except:
                    raise Exception(
                        "Cannot cast '%s' to float in field '%s' for FID=%s" %
                        (val, self.ShapefileFieldIdToLoad, fid))

                polygons.append(polygon)
                self.TRACKER.completeSubtask()

            self.TRACKER.completeTask()

            return polygons
def validateGeometry(geom):
    from shapely.validation import explain_validity

    if explain_validity(geom) == "Valid Geometry":
        return True
    else:
        return False
Example #16
0
 def ensure_ok(self, coords):
     for co in coords:
         shape = geometry.Polygon(co)
         if not shape.exterior.is_simple:
             msg = "La forme du volume n'est pas correcte \nCoordonnees :{co} \nCause :{details}".format(
                 co=co, details=explain_validity(shape))
             raise InconsistentGeometricModel(msg, ids=[self.id])
Example #17
0
def fix_rings(multipolygon, strict=False):
    """
    This resolves a multipolygon with invalid exterior/interior ring pairing. 

    It does so by first sorting the exteriors by z-order (so that the exteriors 
    contained by the most other exteriors are "higher" & get priority). Then, 
    interiors are assigned to their highest containing exterior ring.

    This ensures that the "most interior" interior rings are paired with the 
    "most interior" external rings.

    Requires shapely, may take a bit for shapes with many exteriors/interiors. 

    Parameters
    ---------
    multipolygon: a shapely polygon. (should be invalid due to ring ordering)

    Returns
    -------
    multipolygon: a shapely polygon that should have valid ring ordering. 
                  May be invalid due to other reasons.

    NOTE: This function has undefined behavior for invalid multipolygons. 
    """
    from shapely import geometry as geom
    from shapely.ops import cascaded_union
    from shapely.validation import explain_validity

    vexplain = explain_validity(multipolygon)
    if "hole lies outside shell" not in vexplain.lower():
        if strict:
            from shapely.geos import TopologicalError

            def tell_user(x):
                raise TopologicalError(x)

        else:
            from warnings import warn as tell_user
        tell_user("Shape is invalid: \n{}".format(vexplain))
    exteriors = [geom.Polygon(part.exterior) for part in multipolygon.geoms]
    interiors = [
        geom.Polygon(interior)
        for part in multipolygon.geoms
        for interior in part.interiors
    ]
    zorder = [
        sum([exterior.contains(other_exterior) for other_exterior in exteriors]) - 1
        for exterior in exteriors
    ]
    sort_zorder = np.argsort(zorder)
    zordered_exteriors = np.asarray(exteriors)[sort_zorder]
    polygons = [[exterior] for exterior in exteriors]
    for i, exterior in enumerate(zordered_exteriors):
        owns = [exterior.contains(interior) for interior in interiors]
        owned_interiors = [
            interior for owned, interior in zip(owns, interiors) if owned
        ]
        polygons[i] = exterior.difference(cascaded_union(owned_interiors))
        interiors = [interior for owned, interior in zip(owns, interiors) if not owned]
    return geom.MultiPolygon(polygons)
Example #18
0
    def _get_valid_multipolygon(
            self,
            polygon: Union[Polygon, MultiPolygon]
            ) -> MultiPolygon:
        """Get a valid multipolygon from the input `polygon`

        Validates and if applicable creates a multipolygon from the
        input argument `polygon`

        Parameters
        ----------
        polygon : Polygon or MultiPolygon
            The input polygon or multipolygon which might not be
            topologically valid.

        Returns
        -------
        MultiPolygon
            A validated `shapely` `MultiPolygon` entity
        """

        # TODO: Performance bottleneck for valid checks
        if not polygon.is_valid:
            polygon = ops.unary_union(polygon)

            if not polygon.is_valid:
                polygon = polygon.buffer(0)

            if not polygon.is_valid:
                raise ValueError(explain_validity(polygon))

        if isinstance(polygon, Polygon):
            polygon = MultiPolygon([polygon])

        return polygon
Example #19
0
def show_polygon(polygon):
    print("Polygon")
    print(explain_validity(polygon))
    x, y = polygon.exterior.xy
    plt.plot(x, y)
    plt.axis('equal')
    plt.show()
Example #20
0
def checkGeom(geodataframe):
    """
    Function to check validity of geometry. Returns message from shapely explain_validity if geometry is not 'Valid Geometry'

    Parameters
    ----------
    geodataframe : TYPE
        DESCRIPTION.

    Returns
    -------
    Message.

    """
    for geometry in geodataframe.geometry:
        if explain_validity(geometry) != 'Valid Geometry':
            print(explain_validity(geometry))
Example #21
0
 def ensure_ok(self):
     shape = self.shape # CAUTION Cache the shape
     if shape.is_valid:
         return
     else :
         raise InconsistentGeometricModel("Invalid shapely shape : {details}",
                                          details=explain_validity(shape),
                                          ids=[self.id])
Example #22
0
def validate_geometry(geometry: BaseGeometry):
    if not isinstance(geometry, BaseGeometry):
        raise ValidationError(
            'GeometryField expected a Shapely BaseGeometry child-class.')

    if not geometry.is_valid:
        raise ValidationError('Invalid geometry: %s' %
                              validation.explain_validity(geometry))
Example #23
0
def _contour_to_poly(contour):
    poly = Polygon(contour)
    if not poly.is_valid:
        poly = poly.buffer(0)
    assert poly.is_valid, \
        "Contour %r did not make valid polygon %s because %s" \
        % (contour, poly.wkt, explain_validity(poly))
    return poly
Example #24
0
def _contour_to_poly(contour):
    poly = Polygon(contour)
    if not poly.is_valid:
        poly = poly.buffer(0)
    assert poly.is_valid, \
        "Contour %r did not make valid polygon %s because %s" \
        % (contour, poly.wkt, explain_validity(poly))
    return poly
Example #25
0
def _repair(geom):
    repaired = geom.buffer(0) if geom.geom_type in ["Polygon", "MultiPolygon"] else geom
    if repaired.is_valid:
        return repaired
    else:
        raise TopologicalError(
            "geometry is invalid (%s) and cannot be repaired" % explain_validity(repaired)
        )
Example #26
0
 def ensure_ok(self):
     shape = self.shape  # CAUTION Cache the shape
     if shape.is_valid:
         return
     else:
         msg = "Contour invalide :\nElement : {name} \nCause : {details}".format(
             name=self.name, details=explain_validity(shape))
         raise InconsistentGeometricModel(msg, ids=[self.id])
def importSVGroute(IDT_group):
    IDT_group_dir = IDT_group['IDT_group_dir']
    Tk().withdraw(
    )  # we don't want a full GUI, so keep the root window from appearing
    svg_filename = tkFileDialog.askopenfilename(title='Wafer routing filename',
                                                defaultextension='svg',
                                                initialdir=IDT_group_dir)
    all_points = SVGT.read_colored_path_from_svg(svg_filename)
    route = [[], []]
    for points in all_points['red']:
        polygon = shapely_geom.Polygon(points.T)
        polygon_validity = explain_validity(polygon)
        if polygon_validity == 'Valid Geometry':
            route[0].append(polygon)
        else:
            tkMessageBox.showwarning('Error in svg import', polygon_validity)
    for points in all_points['blue']:
        polygon = shapely_geom.Polygon(points.T)
        polygon_validity = explain_validity(polygon)
        if polygon_validity == 'Valid Geometry':
            route[1].append(polygon)
        else:
            tkMessageBox.showwarning('Error in svg import', polygon_validity)
    route[0] = shapely_geom.MultiPolygon(route[0])
    route[1] = shapely_geom.MultiPolygon(route[1])
    #outbox = route[0].bounds
    #dx = outbox[2]-outbox[0]
    #dy = outbox[3]-outbox[1]
    #x0 = outbox[0]+dx/2
    #y0 = outbox[1]+dy/2
    x0 = 4000
    y0 = 4000
    factor = 1e-5
    route[0] = shapely_affinity.translate(route[0], xoff=-x0, yoff=-y0)
    route[0] = shapely_affinity.scale(route[0],
                                      xfact=factor,
                                      yfact=factor,
                                      origin=(0, 0, 0))
    route[1] = shapely_affinity.translate(route[1], xoff=-x0, yoff=-y0)
    route[1] = shapely_affinity.scale(route[1],
                                      xfact=factor,
                                      yfact=factor,
                                      origin=(0, 0, 0))
    IDT_group['route'] = route
Example #28
0
 def genFeature(self, geom, allGeoms, allBounds, errorCounter):
     try:
         curShape = asShape(geom)
         curBounds = curShape.bounds
         allGeoms.append(curShape)
         allBounds.append(curBounds)
     except Exception as e:
         logging.error(explain_validity(curShape))
         errorCounter += 1
     return allGeoms, allBounds, errorCounter
Example #29
0
    def validation_errors(self):
        if not self.shape_is_valid(self.shape):
            why = explain_validity(self.shape)
            message, x, y = re.findall(r".+?(?=\[)|-?\d+(?:\.\d+)?", why)

            # I Wish this weren't so brittle...
            if "Hole lies outside shell" in message:
                yield UnconnectedError((x, y))
            else:
                yield InvalidShapeError((x, y))
Example #30
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)
Example #31
0
def fix_geom(geom):
    if not geom.is_valid and hasattr(geom, 'buffer'):
        # Attempt to "fix" invalid geometries.
        L.info(explain_validity(geom))
        # Shapely >= 1.8 includes a make_valid method
        # which should be used after it is released. For
        # now use the buffer(0) "hack" that resolves
        # self-intersections pretty well.
        # from shapely.validation import make_valid
        # p = make_valid(p)
        return geom.buffer(0)
Example #32
0
def WayToPoly(wayId, ways, nodes):
	wayData = ways[wayId]
	wayNodes = wayData[0]
	if wayNodes[0] == wayNodes[-1]:
		#Close polygon
		tags = wayData[1]
		pts = []
		for nid in wayNodes:
			if int(nid) not in nodes:
				print "Warning: missing node", nid
				continue
			pts.append(nodes[int(nid)][0])

		#Require at least 3 points
		if len(pts) < 3:
			return None

		poly = Polygon(pts)
		if not poly.is_valid:
			print "Warning: polygon is not valid"
			print explain_validity(poly)
			poly = poly.buffer(0)
		return poly
	else:
		#Unclosed way
		tags = wayData[1]
		pts = []
		for nid in wayNodes:
			if int(nid) not in nodes:
				print "Warning: missing node", nid
				continue
			pts.append(nodes[int(nid)][0])		

		line = LineString(pts)
		if not line.is_valid:
			print "Warning: polygon is not valid"
			print explain_validity(line)
			line = line.buffer(0)
		return line

	return None	
Example #33
0
def make_line(line_points):
    """Instantiate a LineString from a list of point pairs, or return an error string"""
    if len(line_points) < 2:
        return 'has too few points'
    line = LineString(line_points)
    if not line.is_valid:
        return explain_validity(line)
    elif line.is_empty:
        return 'is empty'
    elif line.bounds[0] < 0 or line.bounds[1] < 0:
        return 'is negative'
    return line
Example #34
0
def fix_rings(multipolygon, strict=False):    
    """
    This resolves a multipolygon with invalid exterior/interior ring pairing. 

    It does so by first sorting the exteriors by z-order (so that the exteriors 
    contained by the most other exteriors are "higher" & get priority). Then, 
    interiors are assigned to their highest containing exterior ring.

    This ensures that the "most interior" interior rings are paired with the 
    "most interior" external rings.

    Requires shapely, may take a bit for shapes with many exteriors/interiors. 

    Argument:
    ---------
    multipolygon: a shapely polygon. (should be invalid due to ring ordering)

    Returns:
    --------
    multipolygon: a shapely polygon that should have valid ring ordering. 
                  May be invalid due to other reasons.

    NOTE: This function has undefined behavior for invalid multipolygons. 
    """
    from shapely import geometry as geom
    from shapely.ops import cascaded_union
    from shapely.validation import explain_validity
    vexplain = explain_validity(multipolygon)
    if "hole lies outside shell" not in vexplain.lower():
        if strict:
            from shapely.geos import TopologicalError
            def tell_user(x):
                raise TopologicalError(x)
        else:
            from warnings import warn as tell_user
        tell_user('Shape is invalid for a different reason than'
                  ' hole outside of shell: \n{}'.format(vexplain))
    exteriors = [geom.Polygon(part.exterior) for part in multipolygon.geoms]
    interiors = [geom.Polygon(interior) for part in multipolygon.geoms for interior in part.interiors]
    zorder = [sum([exterior.contains(other_exterior) for other_exterior in exteriors]) - 1
                   for exterior in exteriors]
    sort_zorder = np.argsort(zorder)
    zordered_exteriors = np.asarray(exteriors)[sort_zorder]
    polygons = [[exterior] for exterior in exteriors]
    for i, exterior in enumerate(zordered_exteriors):
        owns = [exterior.contains(interior) for interior in interiors]
        owned_interiors = [interior for owned,interior in zip(owns, interiors)
                           if owned]
        polygons[i] = exterior.difference(cascaded_union(owned_interiors))
        interiors = [interior for owned, interior in zip(owns, interiors)
                     if not owned]
    return geom.MultiPolygon(polygons)
Example #35
0
def GetOuterPolygons(geo, cornerx, cornery):
	outerPoly = []
	assert geo['type'] == "FeatureCollection"
	feature = geo['features'][0]
	geom = feature['geometry']
	for poly in geom['coordinates'][1:]:
		movedPoly = []		
		for pt in poly:
			movedPoly.append((pt[0]+cornerx, pt[1]+cornery))
		outerPoly.append(movedPoly)

	print "Outer Polys", len(outerPoly), cornerx, cornery

	outerPolyShps = []
	for poly in outerPoly:
		newPoly = Polygon(poly)
		if not newPoly.is_valid:
			print "Warning: invalid polygon (1)"
			print explain_validity(newPoly)
			newPoly = newPoly.buffer(0)
		outerPolyShps.append(newPoly)
	return outerPolyShps
Example #36
0
def invalid_geometries(df):
    """Given a GeoDataFrame, returns a list of row indices
    with invalid geometries.

    :param df: :class:`geopandas.GeoDataFrame`
    :rtype: list of int
    """
    invalid = []
    for idx, row in df.iterrows():
        validity = explain_validity(row.geometry)
        if validity != "Valid Geometry":
            invalid.append(idx)
    return invalid
Example #37
0
def GetInnerPolygons(geo, cornerx, cornery):
	innerPoly = []
	for feature in geo['features'][1:]:
		#print feature['type']
		geom = feature['geometry']
		movedPoly = []		
		for pt in geom['coordinates'][0]:
			movedPoly.append((pt[0]+cornerx, pt[1]+cornery))

		innerPoly.append(movedPoly)

	print "Inner Polys", len(innerPoly), cornerx, cornery

	innerPolyShps = []
	for poly in innerPoly:
		newPoly = Polygon(poly)
		if not newPoly.is_valid:
			print "Warning: invalid polygon (2)"
			print explain_validity(newPoly)
			newPoly = newPoly.buffer(0)
		innerPolyShps.append(newPoly)
	return innerPolyShps
Example #38
0
def GetShapelyPolygons(geo, cornerx, cornery, tc):
	print tc
	outerPolys = GetOuterPolygons(geo, cornerx, cornery)
	innerPolys = GetInnerPolygons(geo, cornerx, cornery)

	overlaps = []
	for oPoly in outerPolys:
		matches = []
		for iNum, iPoly in enumerate(innerPolys):
			if oPoly.intersects(iPoly):
				matches.append(iNum)
		overlaps.append(matches)

	combined = []
	for oPoly, matches in zip(outerPolys, overlaps):
		newPoly = copy.deepcopy(oPoly)
		for inInd in matches:
			 newPoly = newPoly.difference(innerPolys[inInd])
		if not newPoly.is_valid:
			print "Warning: invalid polygon (3)"
			print explain_validity(newPoly)
		combined.append(newPoly)
	return combined
Example #39
0
def doPolygonize():
    blocks = polygonize(lines)
    writeBlocks(blocks, args[0] + '-blocks.geojson')

    blocks = polygonize(lines)
    bounds = Polygon([[minlng, minlat], [minlng, maxlat], [maxlng, maxlat],
                      [maxlng, minlat], [minlng, minlat]])
    # Geometry transform function based on pyproj.transform
    project = partial(pyproj.transform, pyproj.Proj(init='EPSG:3785'),
                      pyproj.Proj(init='EPSG:4326'))
    print bounds
    print transform(project, bounds)

    print 'finding holes'
    for index, block in enumerate(blocks):
        if index % 1000 == 0:
            print "diff'd  %s" % (index)
        if not block.is_valid:
            print explain_validity(block)
            print transform(project, block)
        else:
            bounds = bounds.difference(block)
    print bounds
Example #40
0
def make_poly(polygon_points):
    """Instantiate a Polygon from a list of point pairs, or return an error string"""
    if len(polygon_points) < 4:
        return 'has too few points'
    poly = Polygon(polygon_points)
    if POLY_TOLERANCE:
        poly = poly.simplify(POLY_TOLERANCE)
    if not poly.is_valid:
        return explain_validity(poly)
    elif poly.is_empty:
        return 'is empty'
    elif poly.bounds[0] < 0 or poly.bounds[1] < 0:
        return 'is negative'
    return poly
Example #41
0
def split_horiz_by_point(polygon, point):
    """"""
    assert polygon.geom_type == "Polygon" and point.geom_type == "Point"
    nx, ny, xx, xy = polygon.bounds
    if point.x < nx or point.x > xx:
        return [polygon]

    lEnv = sg.LineString([(nx,      ny), (point.x, xy)]).envelope
    rEnv = sg.LineString([(point.x, ny), (xx,      xy)]).envelope
    
    try:
        return [polygon.intersection(lEnv), polygon.intersection(rEnv)]
    except Exception as e:
        print "Geometry error: %s" % validation.explain_validity(polygon)
        return [polygon.buffer(0)]
Example #42
0
def check_bad_geom(geom, osm_id):
    """
    Check if geom is valid
    """
    try:
        # check if we can parse the geom and determine why is geometry
        # invalid
        tst_geom = shapely.wkb.loads(geom.ExportToWkb())
        if tst_geom.is_valid:
            return False
        else:
            reason = explain_validity(tst_geom)
            LOG.error(
                'Bad geometry for the feature %s, reason: %s', osm_id, reason
            )
    except:
        reason = 'BONKERS!'
        LOG.critical('BONKERS geometry for the feature %s', osm_id)

    return reason
 def _LoadPolygons(self):
     with Shapely2ESRI(self.ShapefilePath) as reader:
         
         polygons = []
         self.TRACKER.startProcess(len(reader))
         for polygon in reader.readThrough():
             fid = polygon['FID']
             
             if not polygon.is_valid:
                 raise Exception("The polygon at FID=%s is not valid: %s" %(fid, explain_validity(polygon)))
             
             try:
                 val = polygon[self.ShapefileFieldIdToLoad]
                 polygon[self.ShapefileFieldIdToLoad] = float(val)
             except:
                 raise Exception("Cannot cast '%s' to float in field '%s' for FID=%s" %(val, self.ShapefileFieldIdToLoad, fid))
             
             polygons.append(polygon)
             self.TRACKER.completeSubtask()
             
         self.TRACKER.completeTask()
         
         return polygons
 def validateGeometry(self, geom):
     from shapely.validation import explain_validity
     if (explain_validity(geom) == 'Valid Geometry'):
         return True
     else:
         return False
            vertices_idxs = voronoi.regions[voronoi_region]
            # ignore infinite cells
            if -1 in vertices_idxs:
                continue
            # add lines between all interior points
            points = [(tuple(voronoi.vertices[a]), tuple(voronoi.vertices[b]))
                      for a, b in itertools.combinations(vertices_idxs, 2)]
            ring = MultiLineString(points)
            polygons = list(polygonize([ring]))
            if not polygons:
                log.warning("No polygons detected in line, skipping")
                continue
            else:
                if not polygons[0].is_valid:
                    log.warning("Invalid polygon! %s",
                                explain_validity(polygons[0]))
                    polygons[0] = polygons[0].buffer(0)
                    log.warning("After cleaning validity = %i",
                                polygons[0].is_valid)
                cluster_polygons.append(polygons[0])

        log.info("Merging %i cluster polygons", len(cluster_polygons))
        polygon = cascaded_union(cluster_polygons)
        #import pdb
        #pdb.set_trace()
        log.info("Created polygon for cluster %i with area %0.2f",
                 clusteridx, polygon.area)

        if bounding_polygon is not None:
            polygon = polygon.intersection(bounding_polygon)
        log.info("After AND-ing, the area is: %0.2g", polygon.area)
				geoms = json.load(data_file)
			except Exception as e: 
				print(colored("Error in loading evaluation geometries, please check if it is a valid JSON.", "red"))
				sys.exit(0)

		allf = iter_evals(geoms['features'])
		# iterate over the geometry features.
		for curFeature in allf:
			shp = 0
			featureArea=0
			try:
				# convert the JSON feature in to Shape using Shapely's asShape. 
				shp = asShape(curFeature['geometry'])
			except Exception as e:
				# if there is a error in conversion go to the next shape. 
				print(explain_validity(shp))
				pass
			try:
				assert shp != 0
				# get the bounds of the shape
				bounds = shp.bounds
				# generate the area of the shape
				featureArea = myShapesHelper.generateShapeArea(curFeature, units)
				# generate a random id for the shape
				fid = random.randint(1, 900000000)
				# check the areatype
				areatype = curFeature['properties']['areatype']
				if areatype in evalfeatcollection.keys():
					# input the shape and details in the collections
					evalfeatcollection[areatype].append({'id':fid,'shape':shp, 'bounds':bounds,'areatype':areatype,'area':featureArea, 'allocated':False})
					# insert the bounds and id into the rtree, the id is used to get the shape later. 
Example #47
0
def _locate(segmented, offset=None):
    """Inspired from: https://goo.gl/HYPrR1"""
    # CV_RETR_EXTERNAL to only get external contours.
    _, contours, hierarchy = cv2.findContours(segmented.copy(),
                                              cv2.RETR_CCOMP,
                                              cv2.CHAIN_APPROX_SIMPLE)

    # Note: points are represented as (col, row)-tuples apparently
    transform = identity
    if offset is not None:
        col_off, row_off = offset
        transform = lambda p: affine_transform(p, [1, 0, 0, 1, col_off, row_off])
    components = []
    if len(contours) > 0:
        top_index = 0
        tops_remaining = True
        while tops_remaining:
            exterior = contours[top_index][:, 0, :].tolist()

            interiors = []
            # check if there are childs and process if necessary
            if hierarchy[0][top_index][2] != -1:
                sub_index = hierarchy[0][top_index][2]
                subs_remaining = True
                while subs_remaining:
                    interiors.append(contours[sub_index][:, 0, :].tolist())

                    # check if there is another sub contour
                    if hierarchy[0][sub_index][0] != -1:
                        sub_index = hierarchy[0][sub_index][0]
                    else:
                        subs_remaining = False

            # add component tuple to components only if exterior is a polygon
            if len(exterior) == 1:
                components.append(Point(exterior[0]))
            elif len(exterior) == 2:
                components.append(LineString(exterior))
            elif len(exterior) > 2:
                polygon = Polygon(exterior, interiors)
                polygon = transform(polygon)
                if polygon.is_valid:  # some polygons might be invalid
                    components.append(polygon)
                else:
                    fixed = fix_geometry(polygon)
                    if fixed.is_valid and not fixed.is_empty:
                        components.append(fixed)
                    else:
                        warn("Attempted to fix invalidity '{}' in polygon but failed... "
                             "Output polygon still invalid '{}'".format(explain_validity(polygon),
                                                                        explain_validity(fixed)))

            # check if there is another top contour
            if hierarchy[0][top_index][0] != -1:
                top_index = hierarchy[0][top_index][0]
            else:
                tops_remaining = False

    del contours
    del hierarchy
    return components
Example #48
0
 def test_valid(self):
     self.assertEqual(explain_validity(Point(0, 0)), 'Valid Geometry')
Example #49
0
 def test_valid(self):
     self.failUnlessEqual(explain_validity(Point(0, 0)), 'Valid Geometry')
Example #50
0
def validate_geometry(geometry: BaseGeometry):
    if not isinstance(geometry, BaseGeometry):
        raise ValidationError('GeometryField expected a Shapely BaseGeometry child-class.')

    if not geometry.is_valid:
        raise ValidationError('Invalid geometry: %s' % validation.explain_validity(geometry))
Example #51
0
 def repair_shapefile(self):
     try:
         shpDriver = ogr.GetDriverByName('ESRI Shapefile')
         print("Drivers are ready")
         shpdata = self.shapefilePath
         output = os.path.dirname(shpdata) + os.sep + "rep_" + os.path.basename(shpdata)[4:]
         if os.path.exists(output):
             shpDriver.DeleteDataSource(output)
         ds = shpDriver.CreateDataSource(output)    
         shpSource = shpDriver.Open(shpdata, 0)
         if shpSource is None:
             print('Could not open ' + shpdata)
             sys.exit(1) #exit with an error code
         layer = shpSource.GetLayer()
         numFeatures = layer.GetFeatureCount()
         print('Feature count:' + str(numFeatures))
         inputSR = layer.GetSpatialRef()      
         shplayer = ds.CreateLayer(output, inputSR, ogr.wkbPolygon)       
         inFeature = layer.GetNextFeature()
         for index in range(0, inFeature.GetFieldCount()):
             #fieldList.append(inFeature.GetFieldDefnRef(index))
             shplayer.CreateField(inFeature.GetFieldDefnRef(index))
             print('Created field: ' + inFeature.GetFieldDefnRef(index).name)      
         cnt = 0
         while inFeature:
             cnt = cnt + 1
             f = ogr.Feature(shplayer.GetLayerDefn())
             for index in range(0, f.GetFieldCount()):
                 try:
                     attValue = inFeature.GetField(inFeature.GetFieldDefnRef(index).name)
                     if attValue:
                         f.SetField(f.GetFieldDefnRef(index).name, inFeature.GetField(inFeature.GetFieldDefnRef(index).name))
                 except:
                     print(inFeature.GetFieldDefnRef(index).name + ' - skipping attribute value adding null')
             try:
                 geom = loads(inFeature.GetGeometryRef().ExportToWkb())
                 if geom.is_valid:
                     newGeom = inFeature.geometry()     
                 else:
                     print("Bad geom: " + str(inFeature.GetFID()))
                     print(explain_validity(geom))
                     cleanGeom = geom.buffer(0.0)
                     if cleanGeom.is_valid:
                         print("Geometry is clean")
                         wkbGeom = dumps(cleanGeom)
                         newGeom = ogr.CreateGeometryFromWkb(wkbGeom)
                     else:
                         newGeom = inFeature.geometry()
                 f.SetGeometry(newGeom)
                 if shplayer.CreateFeature(f) != 0:
                     print("Failed to create feature in shapefile.\n")
                     sys.exit(1)
                 f.Destroy()
             except:
                 print('Skipping null geometry')
                 config.run_error_message('repair geom feature failure null geom..')
                 break
             inFeature = layer.GetNextFeature()
         print('Feature count from loop:' + str(cnt))
         ds.Destroy() 
     except:
         config.run_error_message("Repair failure")        
    coords.append([float(xy[0]), float(xy[1])])
    if float(xy[0]) == 180:
      found_anti_meridian = True
  lr = LinearRing(coords)
  if not lr.is_ccw:
    print 'Reversing non-CCW ring'
    r = list(reversed(ls))
    del(ls[:])
    ls.extend(r)

  polygon = Polygon(lr)
  # The invalid polygon is the case of Semisopochnoi Island, which
  # zone crosses the antimeridian.
  if not polygon.is_valid:
    print 'POLYGON IS NOT VALID! : %d' % len(ls)
    explain_validity(polygon)
    if found_anti_meridian:
      print 'Polygon spans anti-meridian'
      # To deal with this case, we'll split the zone into two pieces,
      # one of which is in the eastern hemisphere and one in the
      # western hemisphere. This is purely a tooling issue to make
      # the zone easier to manage with other software.
      xy = ls[0].split(',')
      new_piece = []
      begin_anti_meridian = -1
      end_anti_meridian = -1
      for i in range(0, len(ls)):
        xy = ls[i].split(',')
        if float(xy[0]) == 180:
          # Note: the '-' is to reverse the sign so shapely sees
          # the coordinates correctly.
# -*- coding: utf-8 -*-
import os


from shapely.geometry import Polygon
coords =[(0,0),(0,2),(1,1),(2,2),(2,0),(1,1),(0,0)]
p = Polygon(coords)
from shapely.validation import explain_validity
explain_validity(p)

def Test():
    assert True