叠加分析

裁剪(求异)

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import json
from os.path import realpath
from shapely.geometry import MultiPolygon
from shapely.geometry import asShape
from shapely.wkt import dumps


# define our files input and output locations
input_fairways = realpath("../geodata/pebble-beach-fairways-3857.geojson")
input_greens = realpath("../geodata/pebble-beach-greens-3857.geojson")
output_wkt_sym_diff = realpath("ol3/data/ch06-01_results_sym_diff.js")


# open and load our geojson files as python dictionary
with open(input_fairways) as fairways:
    fairways_data = json.load(fairways)

with open(input_greens) as greens:
    greens_data = json.load(greens)

# create storage list for our new shapely objects
fairways_multiply = []
green_multply = []

# 将GeoJSON中的geometry转化为shapely中的geometry
# create shapely geometry objects for fairways
for feature in fairways_data['features']:
    shape = asShape(feature['geometry'])
    fairways_multiply.append(shape)

# 将GeoJSON中的geometry转化为shapely中的geometry
# create shapely geometry objects for greens
for green in greens_data['features']:
    green_shape = asShape(green['geometry'])
    green_multply.append(green_shape)

#创建MultiPolygon
# create shapely MultiPolygon objects for input analysis
fairway_plys = MultiPolygon(fairways_multiply)
greens_plys = MultiPolygon(green_multply)

#执行裁剪操作
# run the symmetric difference function creating a new Multipolygon
result = fairway_plys.symmetric_difference(greens_plys)

#将要素转化为WKT格式输出
# write the results out to well known text (wkt) with shapely dump
def write_wkt(filepath, features):
    with open(filepath, "w") as f:
        # create a js variable called ply_data used in html
        # Shapely dumps geometry out to WKT
        f.write("var ply_data = '" + dumps(features) + "'")

# write to our output js file the new polygon as wkt
write_wkt(output_wkt_sym_diff, result)

合并(无dissolve)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
from os.path import realpath
import shapefile  # pyshp
from geojson import Feature, FeatureCollection
from shapely.geometry import asShape, MultiPolygon
from shapely.ops import polygonize
from shapely.wkt import dumps


def create_shapes(shapefile_path):
    """
    Convert Shapefile Geometry to Shapely MultiPolygon
    :param shapefile_path: path to a shapefile on disk
    :return: shapely MultiPolygon
    """
    in_ply = shapefile.Reader(shapefile_path)

    # using pyshp reading geometry
    ply_shp = in_ply.shapes()
    ply_records = in_ply.records()
    ply_fields = in_ply.fields
    print(ply_records)
    print(ply_fields)

    if len(ply_shp) > 1:
        #将OGR中的Geometry转化为shapely中的Geometry
        # using python list comprehension syntax
        # shapely asShape to convert to shapely geom
        ply_list = [asShape(feature) for feature in ply_shp]

        #转化为MultiPolygon
        # create new shapely multipolygon
        out_multi_ply = MultiPolygon(ply_list)

        # # equivalent to the 2 lines above without using list comprehension
        # new_feature_list = []
        # for feature in features:
        #     temp = asShape(feature)
        #     new_feature_list.append(temp)
        # out_multi_ply = MultiPolygon(new_feature_list)

        print("converting to MultiPolygon: " + str(out_multi_ply))
    else:
        print("one or no features found")
        shply_ply = asShape(ply_shp)
        out_multi_ply = MultiPolygon(shply_ply)

    return out_multi_ply


def create_union(in_ply1, in_ply2, result_geojson):
    """
    Create union polygon
    :param in_ply1: first input shapely polygon
    :param in_ply2: second input shapely polygon
    :param result_geojson: output geojson file including full file path
    :return: shapely MultiPolygon
    """
    #将外环进行合并
    # union the polygon outer linestrings together
    outer_bndry = in_ply1.boundary.union(in_ply2.boundary)

    #将外环重新生成多边形
    # rebuild linestrings into polygons
    output_poly_list = polygonize(outer_bndry)

    out_geojson = dict(type='FeatureCollection', features=[])

    # generate geojson file output
    for (index_num, ply) in enumerate(output_poly_list):
        #将shapely中的Geometry转化为JSON中的Geometry
        feature = dict(type='Feature', properties=dict(id=index_num))
        feature['geometry'] = ply.__geo_interface__
        out_geojson['features'].append(feature)

    # create geojson file on disk
    json.dump(out_geojson, open(result_geojson, 'w'))

    # create shapely MultiPolygon
    ply_list = []
    for fp in polygonize(outer_bndry):
        ply_list.append(fp)

    out_multi_ply = MultiPolygon(ply_list)

    return out_multi_ply


def write_wkt(filepath, features):
    """

    :param filepath: output path for new javascript file
    :param features: shapely geometry features
    :return:
    """
    with open(filepath, "w") as f:
        # create a javascript variable called ply_data used in html
        # Shapely dumps geometry out to WKT
        f.write("var ply_data = '" + dumps(features) + "'")


def output_geojson_fc(shply_features, outpath):
    """
    Create valid GeoJSON python dictionary
    :param shply_features: shapely geometries
    :param outpath:
    :return: GeoJSON FeatureCollection File
    """

    new_geojson = []
    for feature in shply_features:
        feature_geom_geojson = feature.__geo_interface__
        myfeat = Feature(geometry=feature_geom_geojson,
                         properties={'name': "mojo"})
        new_geojson.append(myfeat)

    out_feat_collect = FeatureCollection(new_geojson)

    with open(outpath, "w") as f:
        f.write(json.dumps(out_feat_collect))


if __name__ == "__main__":

    # define our inputs
    shp1 = realpath("../geodata/temp1-ply.shp")
    shp2 = realpath("../geodata/temp2-ply.shp")

    # define outputs
    out_geojson_file = realpath("../geodata/res_union.geojson")
    output_union = realpath("../geodata/output_union.geojson")
    out_wkt_js = realpath("ol3/data/results_union.js")

    # create our shapely multipolygons for geoprocessing
    in_ply_1_shape = create_shapes(shp1)
    in_ply_2_shape = create_shapes(shp2)

    # run generate union function
    result_union = create_union(in_ply_1_shape, in_ply_2_shape, out_geojson_file)

    # write to our output js file the new polygon as wkt
    write_wkt(out_wkt_js, result_union)

    # write the results out to well known text (wkt) with shapely dump
    geojson_fc = output_geojson_fc(result_union, output_union)

合并(有dissolve)

utils.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from math import sqrt
import shapefile
from shapely.geometry import asShape, MultiPolygon
import json
from shapely.wkt import dumps

# calculate the size of our matplotlib output

GM = (sqrt(5) - 1.0) / 2.0
W = 8.0
H = W * GM
SIZE = (W, H)

# colors for our plots as hex
GRAY = '#B2B3B7'
BLUE = '#6699cc'
YELLOW = '#ffe680'
RED = '#FF1813'
GREEN = '#24CD17'


# functions slightly modified from Sean Gilles http://toblerity.org/shapely/
# used for drawing our results using matplotlib

# matplotlib makers http://matplotlib.org/api/markers_api.html
def plot_coords_line(axis, object, color='#00b700',
                     symbol='o', label="text", mew=1, ms=7):
    """
    mew = marker edge width in points
    ms = marke size in points

    """
    x, y = object.xy
    axis.plot(x, y, symbol, label=label, color=color,
              mew=mew, ms=ms, zorder=1)


def plot_coords_lines(axis, object, color='#999999'):
    for linestring in object:
        x, y = linestring.xy
        axis.plot(x, y, 'o', color=color, zorder=2)


def plot_line(axis, object, color='#00b700', ls='-',
              linewidth=2, c='g'):
    """
    ls is the line style options :[ '-' | '--' | '-.' | ':' | 'steps' | ...]
    """
    x, y = object.xy
    axis.plot(x, y, color=color, linewidth=linewidth, ls=ls, c=c, zorder=1)


def plot_lines(axis, object, color='#00b700'):
    for line in object:
        x, y = line.xy
        axis.plot(x, y, color=color, alpha=0.4, linewidth=1,
                  solid_capstyle='round', zorder=2)


def set_plot_bounds(object, offset=1.0):
    """
    Creates the limits for x and y axis plot

    :param object: input shapely geometry
    :param offset: amount of space around edge of features
    :return: dictionary of x-range and y-range values for
    """
    bounds = object.bounds
    x_min = bounds[0]
    y_min = bounds[1]
    x_max = bounds[2]
    y_max = bounds[3]
    x_range = [x_min - offset, x_max + offset]
    y_range = [y_min - offset, y_max + offset]

    return {'xrange': x_range, 'yrange': y_range}


def create_shapes(shapefile_path):
    """
    Convert Shapefile Geometry to Shapely MultiPolygon
    :param shapefile_path: path to a shapefile on disk
    :return: shapely MultiPolygon
    """
    in_ply = shapefile.Reader(shapefile_path)

    # using pyshp reading geometry
    ply_shp = in_ply.shapes()
    # ply_shp = in_ply.shapeRecords()
    ply_records = in_ply.records()
    ply_fields = in_ply.fields
    # print ply_records
    # print ply_fields

    if len(ply_shp) > 1:
        # using python list comprehension syntax
        # shapely asShape to convert to shapely geom
        ply_list = [asShape(feature) for feature in ply_shp]

        # create new shapely multipolygon
        out_multi_ply = MultiPolygon(ply_list)

        # # equivalent to the 2 lines above without using list comprehension
        # new_feature_list = []
        # for feature in features:
        #     temp = asShape(feature)
        #     new_feature_list.append(temp)
        # out_multi_ply = MultiPolygon(new_feature_list)

        print "converting to MultiPolygon: " + str(out_multi_ply)
    else:
        print "one or no features found"
        shply_ply = asShape(ply_shp)
        out_multi_ply = MultiPolygon(shply_ply)

    return out_multi_ply

def shp_2_geojson_file(shapefile_path, out_geojson):
    # open shapefile
    in_ply = shapefile.Reader(shapefile_path)
    # get a list of geometry and records
    shp_records = in_ply.shapeRecords()
    # get list of fields excluding first list object
    fc_fields = in_ply.fields[1:]

    # using list comprehension to create list of field names
    field_names = [field_name[0] for field_name in fc_fields ]
    my_fc_list = []
    # run through each shape geometry and attribute
    for x in shp_records:
        field_attributes = dict(zip(field_names, x.record))
        geom_j = x.shape.__geo_interface__
        my_fc_list.append(dict(type='Feature', geometry=geom_j,
                               properties=field_attributes))

    # write GeoJSON to a file on disk
    with open(out_geojson, "w") as oj:
        oj.write(json.dumps({'type': 'FeatureCollection',
                        'features': my_fc_list}))


def shp2_geojson_obj(shapefile_path):
    # open shapefile
    in_ply = shapefile.Reader(shapefile_path)
    # get a list of geometry and records
    shp_records = in_ply.shapeRecords()
    # get list of fields excluding first list object
    fc_fields = in_ply.fields[1:]

    # using list comprehension to create list of field names
    field_names = [field_name[0] for field_name in fc_fields ]
    my_fc_list = []
    # run through each shape geometry and attribute
    for x in shp_records:
        field_attributes = dict(zip(field_names, x.record))
        geom_j = x.shape.__geo_interface__
        my_fc_list.append(dict(type='Feature', geometry=geom_j,
                               properties=field_attributes))

    geoj_json_obj = {'type': 'FeatureCollection',
                    'features': my_fc_list}

    return geoj_json_obj


def out_geoj(list_geom, out_geoj_file):
    out_geojson = dict(type='FeatureCollection', features=[])

    # generate geojson file output
    for (index_num, ply) in enumerate(list_geom):
        feature = dict(type='Feature', properties=dict(id=index_num))
        feature['geometry'] = ply.__geo_interface__
        out_geojson['features'].append(feature)

    # create geojson file on disk
    json.dump(out_geojson, open(out_geoj_file, 'w'))


def write_wkt(filepath, shply_geom):
    """

    :param filepath: output path for new javascript file
    :param shply_geom: shapely geometry features
    :return:
    """
    with open(filepath, "w") as f:
        # create a javascript variable called ply_data used in html
        # Shapely dumps geometry out to WKT
        f.write("var ply_data = '" + dumps(shply_geom) + "'")

union_dissolve.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from shapely.geometry import MultiPolygon
from shapely.ops import cascaded_union
from os.path import realpath
from utils import create_shapes
from utils import out_geoj
from utils import write_wkt


def check_geom(in_geom):
    """
    :param in_geom: input valid Shapely geometry objects
    :return: Shapely MultiPolygon cleaned
    """
    plys = []
    for g in in_geom:
        # if geometry is NOT valid
        if not g.is_valid:
            print("Oh no invalid geometry")
            # clean polygon with buffer 0 distance trick
            new_ply = g.buffer(0)
            print("now lets make it valid")
            # add new geometry to list
            plys.append(new_ply)
        else:
            # add valid geometry to list
            plys.append(g)
    # convert new polygons into a new MultiPolygon
    out_new_valid_multi = MultiPolygon(plys)
    return out_new_valid_multi


if __name__ == "__main__":

    # input NOAA Shapefile
    shp = realpath("../geodata/temp-all-warn-week.shp")

    # output union_dissolve results as GeoJSON
    out_geojson_file = realpath("../geodata/ch06-03_union_dissolve.geojson")

    out_wkt_js = realpath("ol3/data/ch06-03_results_union.js")

    # input Shapefile and convert to Shapely geometries
    shply_geom = create_shapes(shp)

    # Check the Shapely geometries if they are valid if not fix them
    new_valid_geom = check_geom(shply_geom)

#进行级联合并 # run our union with dissolve dissolve_result =
 cascaded_union(new_valid_geom)

    # output the resulting union dissolved polygons to GeoJSON file
    out_geoj(dissolve_result, out_geojson_file)

    write_wkt(out_wkt_js, dissolve_result)

identity

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from shapely.geometry import asShape, MultiPolygon
from utils import shp2_geojson_obj, out_geoj, write_wkt
from os.path import realpath

def create_polys(shp_data):
    """
    :param shp_data: input GeoJSON
    :return: MultiPolygon Shapely geometry
    """
    plys = []
    for feature in shp_data['features']:
        shape = asShape(feature['geometry'])
        plys.append(shape)

    new_multi = MultiPolygon(plys)
    return new_multi


def create_out(res1, res2):
    """

    :param res1: input feature
    :param res2: identity feature
    :return: MultiPolygon identity results
    """
    identity_geoms = []

    for g1 in res1:
        identity_geoms.append(g1)
    for g2 in res2:
        identity_geoms.append(g2)

    out_identity = MultiPolygon(identity_geoms)
    return out_identity


if __name__ == "__main__":
    # out two input test Shapefiles
    shp1 = realpath("../geodata/temp1-ply.shp")
    shp2 = realpath("../geodata/temp2-ply.shp")

    # output resulting GeoJSON file
    out_geojson_file = realpath("../geodata/result_identity.geojson")

    output_wkt_identity = realpath("ol3/data/ch06-04_results_identity.js")


    # convert our Shapefiles to GeoJSON
    # then to python dictionaries
    shp1_data = shp2_geojson_obj(shp1)
    shp2_data = shp2_geojson_obj(shp2)

    # transform our GeoJSON data into Shapely geom objects
    shp1_polys = create_polys(shp1_data)
    shp2_polys = create_polys(shp2_data)

    #先计算不同处,再计算相同处
    # run the difference and intersection
    res_difference = shp1_polys.difference(shp2_polys)
    res_intersection = shp1_polys.intersection(shp2_polys)

    # combine the difference and intersection polygons into results
    result_identity = create_out(res_difference, res_intersection)

    # export identity results to a GeoJSON
    out_geoj(result_identity, out_geojson_file)

    # write out new javascript variable with wkt geometry
    write_wkt(output_wkt_identity, result_identity )
原文地址:https://www.cnblogs.com/gispathfinder/p/5790070.html