提交 af248d66aa097e4894d38db8e8b57af2a14ca386

作者 nheweijun
1 个父辈 978f7fa2

2022.03.22 备份

... ... @@ -11,6 +11,8 @@ from ..models import Database,DES
11 11
12 12 from app.util.component.ApiTemplate import ApiTemplate
13 13 from app.util.component.ModelVisitor import ModelVisitor
  14 +from app.util.component.UserAlias import UserAlias
  15 +
14 16 class Api(ApiTemplate):
15 17 api_name = "获取数据库列表"
16 18 def process(self):
... ... @@ -32,6 +34,9 @@ class Api(ApiTemplate):
32 34
33 35 database = database.limit(page_size).offset(page_index * page_size).all()
34 36 res["data"]["list"] =[]
  37 +
  38 + user_alias = UserAlias()
  39 +
35 40 for datab in database:
36 41 # 测试连接
37 42 try:
... ... @@ -45,6 +50,8 @@ class Api(ApiTemplate):
45 50 datab_json = ModelVisitor.database_to_json(datab)
46 51 datab_json["table_count"] = table_count
47 52 datab_json["available"] = available
  53 + datab_json["display_name"] = user_alias.get_alias(datab_json["creator"])
  54 +
48 55 del datab_json["connectstr"]
49 56 res["data"]["list"].append(datab_json)
50 57
... ...
... ... @@ -4,12 +4,13 @@
4 4
5 5
6 6 from ..models import Table,Catalog
7   -
  7 +from app.modules.auth.models import User
8 8 from sqlalchemy import or_,and_
9   -
  9 +from sqlalchemy.orm import Query
10 10 from app.util.component.ApiTemplate import ApiTemplate
11   -
  11 +from app.util.component.UserAlias import UserAlias
12 12 from app.util.component.ModelVisitor import ModelVisitor
  13 +
13 14 class Api(ApiTemplate):
14 15 api_name = "表列表"
15 16 def process(self):
... ... @@ -37,10 +38,11 @@ class Api(ApiTemplate):
37 38
38 39 sort = int(self.para.get("sort","1"))
39 40 if sort.__eq__(1):
40   - tables = Table.query.order_by(Table.update_time.desc(),Table.name)
  41 + tables:Query = Table.query.order_by(Table.update_time.desc(),Table.name)
41 42 else:
42 43 tables = Table.query.order_by(Table.name)
43 44
  45 +
44 46 #过滤spatial_ref_sys
45 47 tables = tables.filter(Table.name.notin_(["spatial_ref_sys"]))
46 48
... ... @@ -75,8 +77,12 @@ class Api(ApiTemplate):
75 77 tables = tables.limit(page_size).offset(page_index * page_size).all()
76 78 res["data"]["list"]=[]
77 79
  80 +
  81 + user_alias = UserAlias()
78 82 for t in tables:
79   - res["data"]["list"].append(ModelVisitor.table_to_json(t))
  83 + table_json = ModelVisitor.table_to_json(t)
  84 + table_json["display_name"] = user_alias.get_alias(table_json["creator"])
  85 + res["data"]["list"].append(table_json)
80 86
81 87 res["result"] = True
82 88 except Exception as e:
... ...
... ... @@ -10,7 +10,8 @@ from ..models import Task
10 10 from app.util.component.ApiTemplate import ApiTemplate
11 11 from app.util.component.ModelVisitor import ModelVisitor
12 12 import json
13   -
  13 +from app.modules.auth.models import User
  14 +from app.util.component.UserAlias import UserAlias
14 15
15 16 class Api(ApiTemplate):
16 17 api_name = "任务列表"
... ... @@ -33,7 +34,7 @@ class Api(ApiTemplate):
33 34
34 35 state = parameter.get("state")
35 36
36   - if creator:
  37 + if creator and creator !="admin":
37 38 tasks = tasks.filter_by(creator=creator)
38 39 if start_time and end_time:
39 40 tasks = tasks.filter(Task.create_time.between(start_time, end_time))
... ... @@ -52,6 +53,8 @@ class Api(ApiTemplate):
52 53 res["data"]["list"] = [ModelVisitor.task_to_json(task) for task in tasks]
53 54
54 55 try:
  56 + user_alias = UserAlias()
  57 +
55 58 for task_info in res["data"]["list"]:
56 59 if task_info["task_type"]==1:
57 60 task_info["layers"] = []
... ... @@ -60,6 +63,7 @@ class Api(ApiTemplate):
60 63 for key in m.get("layer").keys():
61 64
62 65 task_info["layers"].append({"name":key,"new_name":m.get("layer").get(key)})
  66 + task_info["display_name"] = user_alias.get_alias(task_info["creator"])
63 67 except:
64 68 pass
65 69
... ...
... ... @@ -39,9 +39,15 @@ class Api(ApiTemplate):
39 39 try:
40 40
41 41 this_time = datetime.datetime.now()
42   - service_guid = uuid.uuid1().__str__ida()
  42 + service_guid = uuid.uuid1().__str__()
43 43 map_service_guid = uuid.uuid1().__str__()
44 44
  45 + token = self.para.get("token")
  46 + creator = self.para.get("creator")
  47 + if creator is None:
  48 + raise Exception("用户检验失败!")
  49 +
  50 +
45 51 # 逻辑是,先调用引擎接口,引擎说可以,才做持久化
46 52 project_file = self.create_projectfile(self.para)
47 53 para = {"name":self.para.get("name"),
... ... @@ -72,7 +78,7 @@ class Api(ApiTemplate):
72 78 guid = service_guid,
73 79 name = self.para.get("name"),
74 80 title = self.para.get("title"),
75   - creator=self.para.get("creator"),
  81 + creator=creator,
76 82 state = 1,
77 83 create_time = this_time,
78 84 update_time = this_time,
... ... @@ -103,7 +109,9 @@ class Api(ApiTemplate):
103 109 db.session.commit()
104 110
105 111 res["data"] = service_guid
  112 + res["url"] = ""
106 113 res["result"] = True
  114 +
107 115 except Exception as e:
108 116 db.session.rollback()
109 117 raise e
... ... @@ -294,6 +302,12 @@ class Api(ApiTemplate):
294 302 "type": "string",
295 303 "description": "表名",
296 304 "required": "true"},
  305 +
  306 + {"name": "token",
  307 + "in": "formData",
  308 + "type": "string",
  309 + "description": "token",
  310 + "required": "true"},
297 311 ],
298 312 "responses": {
299 313 200: {
... ...
... ... @@ -11,6 +11,7 @@ from sqlalchemy import or_
11 11 import requests
12 12 import re
13 13 from .util.ServiceType import ServiceType
  14 +from app.util.component.UserAlias import UserAlias
14 15
15 16 class Api(ApiTemplate):
16 17 api_name = "服务列表"
... ... @@ -99,6 +100,12 @@ class Api(ApiTemplate):
99 100 services_json = sorted(services_json,key=lambda x:x["update_time"],reverse=True)
100 101
101 102 res["data"]["list"] = services_json[page_index*page_size:(page_index+1)*page_size]
  103 +
  104 + # 显示别名
  105 + user_alias = UserAlias()
  106 + for service_json in res["data"]["list"]:
  107 + service_json["display_name"] = user_alias.get_alias(service_json["creator"])
  108 +
102 109 res["result"] = True
103 110
104 111 except Exception as e:
... ...
... ... @@ -15,6 +15,7 @@ class ParameterUtil:
15 15 parameter = dict()
16 16 parameter.update(request.args.items())
17 17 parameter.update(request.form.items())
  18 +
18 19 try:
19 20 request_json = request.get_json()
20 21 if json:
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/17
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.modules.auth.models import User
  7 +
  8 +class UserAlias:
  9 + def __init__(self):
  10 + self.creator_dict = {}
  11 +
  12 + def get_alias(self,creator):
  13 + alias = self.creator_dict.get(creator)
  14 + if alias:
  15 + return alias
  16 + else:
  17 + user = User.query.filter_by(username=creator).one_or_none()
  18 + if user:
  19 + self.creator_dict[creator] = user.displayname
  20 + else:
  21 + self.creator_dict[creator] = ""
  22 + return self.creator_dict[creator]
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/14
  4 +#email: nheweijun@sina.com
  5 +import numpy as np
  6 +import matplotlib.pyplot as plt
  7 +from matplotlib.collections import PolyCollection,LineCollection
  8 +import matplotlib as mpl
  9 +from PIL import Image
  10 +import os
  11 +
  12 +
  13 +def draw(geom):
  14 +
  15 +
  16 +
  17 + rectangle = [(0, 0), (0, 1), (1, 1), (1, 0),(0, 0)]
  18 + # hexagon = [(0, 0), (0, 1), (1, 2), (2, 1), (2, 0), (1, -1)]
  19 + l_shape = [(0, 0), (0, 3), (1, 3), (1, 1), (3, 1), (3, 0)]
  20 + # concave = [(0, 0), (0, 3), (1, 3), (1, 1), (2, 1), (2, 3), (3, 3), (3, 0)]
  21 +
  22 + for points in [rectangle,l_shape]:
  23 + xs, ys = zip(*points)
  24 + # plt.plot(xs, ys, 'o')
  25 + plt.plot(xs, ys, '-')
  26 +
  27 + plt.axis('off')
  28 + png_path = "F:/temp.png"
  29 + plt.savefig(png_path)
  30 + png = Image.open(png_path)
  31 + tif_path = "F:/temp.tif"
  32 + png.save(tif_path)
  33 + os.remove(png_path)
  34 +
  35 +
  36 +if __name__ == '__main__':
  37 + draw()
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/15
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo import ogr
  7 +from osgeo.ogr import *
  8 +import math
  9 +import os
  10 +
  11 +class util:
  12 + @classmethod
  13 + def envelop_2_polygon(cls,env):
  14 + ring = ogr.Geometry(ogr.wkbLinearRing)
  15 + ring.AddPoint(env[0], env[2])
  16 + ring.AddPoint(env[0], env[3])
  17 + ring.AddPoint(env[1], env[3])
  18 + ring.AddPoint(env[1], env[2])
  19 + ring.AddPoint(env[0], env[2])
  20 + # Create polygon
  21 + poly = ogr.Geometry(ogr.wkbPolygon)
  22 + poly.AddGeometry(ring)
  23 + return poly
  24 +
  25 +
  26 +p1= util.envelop_2_polygon([0,1,0,1])
  27 +p2 = util.envelop_2_polygon([2,3,2,3])
  28 +
  29 +lll = p1.GetGeometryRef(0)
  30 +print(lll.GetPoints())
  31 +
  32 +
... ...
  1 +#!/bin/env python
  2 +
  3 +##
  4 +## calculate the concave hull of a set of points
  5 +## see: CONCAVE HULL: A K-NEAREST NEIGHBOURS APPROACH
  6 +## FOR THE COMPUTATION OF THE REGION OCCUPIED BY A
  7 +## SET OF POINTS
  8 +## Adriano Moreira and Maribel Yasmina Santos 2007
  9 +##
  10 +
  11 +import numpy as np
  12 +import scipy.spatial as spt
  13 +import matplotlib.pyplot as plt
  14 +from matplotlib.path import Path
  15 +from test.zonghe import lineintersect as li
  16 +
  17 +def GetFirstPoint(dataset):
  18 + ''' Returns index of first point, which has the lowest y value '''
  19 + # todo: what if there is more than one point with lowest y?
  20 + imin = np.argmin(dataset[:,1])
  21 + return dataset[imin]
  22 +
  23 +def GetNearestNeighbors(dataset, point, k):
  24 + ''' Returns indices of k nearest neighbors of point in dataset'''
  25 + # todo: experiment with leafsize for performance
  26 + mytree = spt.cKDTree(dataset,leafsize=10)
  27 + distances, indices = mytree.query(point,k)
  28 + # todo: something strange here, we get more indices than points in dataset
  29 + # so have to do this
  30 + return dataset[indices[:dataset.shape[0]]]
  31 +
  32 +def SortByAngle(kNearestPoints, currentPoint, prevPoint):
  33 + ''' Sorts the k nearest points given by angle '''
  34 + angles = np.zeros(kNearestPoints.shape[0])
  35 + i = 0
  36 + for NearestPoint in kNearestPoints:
  37 + # calculate the angle
  38 + angle = np.arctan2(NearestPoint[1]-currentPoint[1],
  39 + NearestPoint[0]-currentPoint[0]) - \
  40 + np.arctan2(prevPoint[1]-currentPoint[1],
  41 + prevPoint[0]-currentPoint[0])
  42 + angle = np.rad2deg(angle)
  43 + # only positive angles
  44 + angle = np.mod(angle+360,360)
  45 + #print NearestPoint[0], NearestPoint[1], angle
  46 + angles[i] = angle
  47 + i=i+1
  48 + return kNearestPoints[np.argsort(angles)]
  49 +
  50 +# def plotPoints(dataset):
  51 +# plt.plot(dataset[:,0],dataset[:,1],'o',markersize=10,markerfacecolor='0.75',
  52 +# markeredgewidth=1)
  53 +# plt.axis('equal')
  54 +# plt.axis([min(dataset[:,0])-0.5,max(dataset[:,0])+0.5,min(dataset[:,1])-0.5,
  55 +# max(dataset[:,1])+0.5])
  56 +# plt.show()
  57 +#
  58 +# def plotPath(dataset, path):
  59 +# plt.plot(dataset[:,0],dataset[:,1],'o',markersize=10,markerfacecolor='0.65',
  60 +# markeredgewidth=0)
  61 +# path = np.asarray(path)
  62 +# plt.plot(path[:,0],path[:,1],'o',markersize=10,markerfacecolor='0.55',
  63 +# markeredgewidth=0)
  64 +# plt.plot(path[:,0],path[:,1],'-',lw=1.4,color='k')
  65 +# plt.axis('equal')
  66 +# plt.axis([min(dataset[:,0])-0.5,max(dataset[:,0])+0.5,min(dataset[:,1])-0.5,
  67 +# max(dataset[:,1])+0.5])
  68 +# plt.axis('off')
  69 +# plt.savefig('./doc/figure_1.png', bbox_inches='tight')
  70 +# plt.show()
  71 +
  72 +def removePoint(dataset, point):
  73 + delmask = [np.logical_or(dataset[:,0]!=point[0],dataset[:,1]!=point[1])]
  74 + newdata = dataset[delmask]
  75 + return newdata
  76 +
  77 +
  78 +def concaveHull(dataset, k):
  79 + assert k >= 3, 'k has to be greater or equal to 3.'
  80 + points = dataset
  81 + # todo: remove duplicate points from dataset
  82 + # todo: check if dataset consists of only 3 or less points
  83 + # todo: make sure that enough points for a given k can be found
  84 +
  85 + firstpoint = GetFirstPoint(points)
  86 + # init hull as list to easily append stuff
  87 + hull = []
  88 + # add first point to hull
  89 + hull.append(firstpoint)
  90 + # and remove it from dataset
  91 + points = removePoint(points,firstpoint)
  92 + currentPoint = firstpoint
  93 + # set prevPoint to a Point righ of currentpoint (angle=0)
  94 + prevPoint = (currentPoint[0]+10, currentPoint[1])
  95 + step = 2
  96 +
  97 + while ( (not np.array_equal(firstpoint, currentPoint) or (step==2)) and points.size > 0 ):
  98 + if ( step == 5 ): # we're far enough to close too early
  99 + points = np.append(points, [firstpoint], axis=0)
  100 + kNearestPoints = GetNearestNeighbors(points, currentPoint, k)
  101 + cPoints = SortByAngle(kNearestPoints, currentPoint, prevPoint)
  102 + # avoid intersections: select first candidate that does not intersect any
  103 + # polygon edge
  104 + its = True
  105 + i = 0
  106 + while ( (its==True) and (i<cPoints.shape[0]) ):
  107 + i=i+1
  108 + if ( np.array_equal(cPoints[i-1], firstpoint) ):
  109 + lastPoint = 1
  110 + else:
  111 + lastPoint = 0
  112 + j = 2
  113 + its = False
  114 + while ( (its==False) and (j<np.shape(hull)[0]-lastPoint) ):
  115 + its = li.doLinesIntersect(hull[step-1-1], cPoints[i-1],
  116 + hull[step-1-j-1],hull[step-j-1])
  117 + j=j+1
  118 + if ( its==True ):
  119 + print("all candidates intersect -- restarting with k = ",k+1)
  120 + return concaveHull(dataset,k+1)
  121 + prevPoint = currentPoint
  122 + currentPoint = cPoints[i-1]
  123 + # add current point to hull
  124 + hull.append(currentPoint)
  125 + points = removePoint(points,currentPoint)
  126 + step = step+1
  127 + # check if all points are inside the hull
  128 + p = Path(hull)
  129 + pContained = p.contains_points(dataset, radius=0.0000000001)
  130 + if (not pContained.all()):
  131 + print("not all points of dataset contained in hull -- restarting with k = ",k+1)
  132 + return concaveHull(dataset, k+1)
  133 +
  134 + print("finished with k = ",k)
  135 + return hull
  136 +
  137 +
  138 +
  139 +if __name__ == '__main__':
  140 +
  141 +
  142 +
  143 + points_E = np.array([[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[6,2],[6,3],[5,3],[4,3],
  144 + [3,3],[3,4],[3,5],[4,5],[5,5],[5,6],[5,7],[4,7],[3,7],[3,8],
  145 + [3,9],[4,9],[5,9],[6,9],[6,10],[6,11],[5,11],[4,11],[3,11],[2,11],
  146 + [1,11],[1,10],[1,9],[1,8],[1,7],[1,6],[1,5],[1,4],[1,3],[1,2],
  147 + [5,2],[4,2],[3,2],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],
  148 + [2,9],[2,10],[3,10],[4,10],[5,10],[3,6],[4,6],[5,6],[4.5,7],[3,8.5],
  149 + ])
  150 +
  151 + print(concaveHull(points_E, 3))
  152 +
  153 +
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/15
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo import ogr
  7 +from osgeo.ogr import *
  8 +import math
  9 +import os
  10 +import copy
  11 +from test.zonghe.RepresentPoint import RepresentPoint
  12 +
  13 +
  14 +
  15 +class DelauneyNode:
  16 +
  17 + def __init__(self, rp):
  18 + self.rp = rp
  19 + self.children_nodes = list()
  20 + self.children_delauney_lines = list()
  21 +
  22 + def get_all_node(self):
  23 + for node in self.children_nodes:
  24 + yield node.get_all_node()
  25 + yield self
  26 +
  27 + def get_rps(self):
  28 + for node in self.children_nodes:
  29 + for rp in node.get_rps():
  30 + yield rp
  31 + yield self.rp
  32 +
  33 + def get_polygons(self):
  34 + for node in self.children_nodes:
  35 + for rp in node.get_rps():
  36 + yield rp.polygon
  37 + yield self.rp.polygon
  38 +
  39 + def get_delauney_lines(self):
  40 + for node in self.children_nodes:
  41 + for ll in node.get_delauney_lines():
  42 + yield ll
  43 + for l in self.children_delauney_lines:
  44 + yield l
  45 +
  46 + def add_children(self,node,delauney_line):
  47 + self.children_nodes.append(node)
  48 + self.children_delauney_lines.append(delauney_line)
  49 +
  50 +class DelauneyLine:
  51 +
  52 + def __init__(self,rp1,rp2):
  53 +
  54 + self.rp1 = rp1
  55 + self.rp2 = rp2
  56 + self.distance = rp1.polygon.Distance(rp2.polygon)
  57 +
  58 + self.line = ogr.Geometry(ogr.wkbLineString)
  59 + self.line.AddPoint(self.rp1.point.GetX(),self.rp1.point.GetY())
  60 + self.line.AddPoint(self.rp2.point.GetX(),self.rp2.point.GetY())
  61 +
  62 +
  63 +class DelauneyMinTree:
  64 +
  65 + def __init__(self):
  66 + self.delauney_lines_list = list()
  67 + self.rps = set()
  68 +
  69 + def append(self,delauney_line):
  70 + # self.delauney_lines.add(delauney_line)
  71 +
  72 + self.rps.add(delauney_line.rp1)
  73 + self.rps.add(delauney_line.rp2)
  74 +
  75 + self.delauney_lines_list.append(delauney_line)
  76 +
  77 + def get_rps(self):
  78 + return self.rps
  79 +
  80 + def get_other_relate_delauney_lines(self,other_delauney_lines_kv):
  81 + other_relate_delauney_lines = []
  82 + for rp in self.rps:
  83 + other_relate_delauney_lines.extend(other_delauney_lines_kv.get(rp))
  84 + return other_relate_delauney_lines
  85 +
  86 + def get_other_rp(self,delauney_line):
  87 + rp1 = delauney_line.rp1
  88 + rp2 = delauney_line.rp2
  89 +
  90 + if not self.rps.__contains__(rp1):
  91 + return rp1
  92 + if not self.rps.__contains__(rp2):
  93 + return rp2
  94 + return None
  95 +
  96 +
  97 +
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/15
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo import ogr
  7 +from osgeo.ogr import *
  8 +import math
  9 +import os
  10 +import copy
  11 +class RepresentPoint:
  12 +
  13 + def __init__(self,point,polygon):
  14 + self.point = point
  15 + self.polygon = polygon
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/15
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from osgeo import ogr
  8 +from osgeo.ogr import *
  9 +import math
  10 +import os
  11 +import copy
  12 +
  13 +class ShapeData:
  14 +
  15 + driver = ogr.GetDriverByName("ESRI Shapefile")
  16 +
  17 + def __init__(self,path):
  18 +
  19 + self.ds: DataSource = self.driver.Open(path, 0)
  20 + if not self.ds:
  21 + raise Exception("打开数据失败!")
  22 + self.layer: Layer = self.ds.GetLayer(0)
  23 +
  24 +
  25 + def get_polygons(self):
  26 +
  27 + polygons = []
  28 + for feature in self.layer:
  29 + f:Feature = feature
  30 + geom : Geometry = copy.deepcopy(f.GetGeometryRef())
  31 + if geom.GetGeometryType() == 3 or geom.GetGeometryType() == -2147483645:
  32 + polygons.append(geom)
  33 + if geom.GetGeometryType() == 6 or geom.GetGeometryType() == -2147483642:
  34 + for i in range(geom.GetGeometryCount()):
  35 + polygons.append(geom.GetGeometryRef(i))
  36 + return polygons
  37 +
  38 + def close(self):
  39 + self.ds.Destroy()
  40 +
  41 +
  42 +
  43 +
  44 + @classmethod
  45 + def create_by_layer(cls,path,layer:Layer):
  46 + data_source: DataSource = cls.driver.CreateDataSource(path)
  47 + data_source.CopyLayer(layer,layer.GetName())
  48 + data_source.Destroy()
  49 +
  50 + @classmethod
  51 + def create_by_scheme(cls,path,name,sr,geo_type,scheme,features):
  52 + data_source: DataSource = cls.driver.CreateDataSource(path)
  53 + layer :Layer = data_source.CreateLayer(name, sr, geo_type)
  54 + if scheme:
  55 + layer.CreateFields(scheme)
  56 + for feature in features:
  57 + layer.CreateFeature(feature)
  58 + data_source.Destroy()
  59 +
  60 + @classmethod
  61 + def create_point(cls,path,name,point):
  62 + data_source: DataSource = cls.driver.CreateDataSource(path)
  63 + layer :Layer = data_source.CreateLayer(name, None, ogr.wkbPoint)
  64 +
  65 + feat_new = ogr.Feature(layer.GetLayerDefn())
  66 + feat_new.SetGeometry(point)
  67 + layer.CreateFeature(feat_new)
  68 + data_source.Destroy()
  69 +
  70 + @classmethod
  71 + def create_shp_fromwkts(cls,path,name,wkts):
  72 +
  73 + geo_type = None
  74 + geoms = []
  75 + for wkt in wkts:
  76 + geom : Geometry = ogr.CreateGeometryFromWkt(wkt)
  77 + if geo_type is None:
  78 + geo_type = geom.GetGeometryType()
  79 + geoms.append(geom)
  80 +
  81 + if os.path.exists(path):
  82 +
  83 + pre_name = ".".join(path.split(".")[0:-1])
  84 + for bac in ["dbf","prj","cpg","shp","shx","sbn","sbx"]:
  85 + try:
  86 + os.remove(pre_name+"."+bac)
  87 + except Exception as e:
  88 + pass
  89 +
  90 + data_source: DataSource = cls.driver.CreateDataSource(path)
  91 + layer :Layer = data_source.CreateLayer(name, None, geo_type)
  92 +
  93 + for geom in geoms:
  94 + feat_new = ogr.Feature(layer.GetLayerDefn())
  95 + feat_new.SetGeometry(geom)
  96 + layer.CreateFeature(feat_new)
  97 + data_source.Destroy()
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/15
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo import ogr
  7 +from osgeo.ogr import *
  8 +import math
  9 +import os
  10 +import copy
  11 +
  12 +class Util:
  13 + @classmethod
  14 + def envelop_2_polygon(cls,env):
  15 + ring = ogr.Geometry(ogr.wkbLinearRing)
  16 + ring.AddPoint(env[0], env[2])
  17 + ring.AddPoint(env[0], env[3])
  18 + ring.AddPoint(env[1], env[3])
  19 + ring.AddPoint(env[1], env[2])
  20 + ring.AddPoint(env[0], env[2])
  21 + # Create polygon
  22 + poly = ogr.Geometry(ogr.wkbPolygon)
  23 + poly.AddGeometry(ring)
  24 + return poly
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/8
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from osgeo import ogr
  8 +from osgeo.ogr import *
  9 +import math
  10 +import os
  11 +import copy
  12 +os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
  13 +
  14 +from test.zonghe.ShapeData import ShapeData
  15 +from test.zonghe.Delauney import DelauneyNode,DelauneyLine,DelauneyMinTree
  16 +from test.zonghe.RepresentPoint import RepresentPoint
  17 +from test.zonghe.Util import Util
  18 +import cv2
  19 +
  20 +class Zonghe:
  21 +
  22 + data:ShapeData
  23 + area_threshold = 100.0
  24 + buffer_threshold = 100.0
  25 + distance_buffer_threshold = 2.114691025217302e-04
  26 +
  27 + def __init__(self,data):
  28 + self.data = data
  29 +
  30 +
  31 + #只处理Polygon,MultiPolygon要拆开
  32 + def get_polygon_reprecent_point(self,polygon:Geometry):
  33 +
  34 + polygon_env = polygon.GetEnvelope()
  35 +
  36 + area_thre = polygon.GetArea()/self.area_threshold
  37 +
  38 + line_length = math.sqrt(math.pow(polygon_env[1] - polygon_env[0],2) + math.pow(polygon_env[3] - polygon_env[2],2))
  39 +
  40 +
  41 + short_length = min(polygon_env[1]-polygon_env[0],polygon_env[3]-polygon_env[2])
  42 +
  43 +
  44 +
  45 + center:Geometry = polygon.Centroid()
  46 + # print(center)
  47 +
  48 +
  49 + # 提前return
  50 + if polygon.Contains(center):
  51 + # print("\"" + center.ExportToWkt() + "\",")
  52 + return RepresentPoint(center, polygon)
  53 +
  54 +
  55 + last_state = None
  56 + line = None
  57 + calculate_time = 0
  58 +
  59 + direction = self.get_direction(polygon, center, line_length)
  60 +
  61 +
  62 + in_hole = False
  63 + in_hole_line = None
  64 +
  65 +
  66 + #无孔Polygon
  67 + if polygon.GetGeometryCount() == 1:
  68 + polygon_line = ogr.ForceToLineString(polygon)
  69 +
  70 + # 有孔Polygon,要分2种情况
  71 + else:
  72 + polygon_line = ogr.ForceToLineString(polygon.GetGeometryRef(0))
  73 + for i in range(1,polygon.GetGeometryCount()):
  74 + hole_line = polygon.GetGeometryRef(i)
  75 + hole_polygon : Geometry = ogr.ForceToPolygon(hole_line)
  76 + if hole_polygon.Contains(center):
  77 + in_hole = True
  78 + direction = range(0,190,10)
  79 + in_hole_line = ogr.ForceToLineString(hole_line)
  80 + # print("in_hole")
  81 +
  82 + angle1,angle2=None,None
  83 +
  84 + for angle in direction:
  85 +
  86 + if in_hole:
  87 + line = self.get_doubleline(center.GetX(),center.GetY(),angle,line_length)
  88 + else:
  89 + line = self.get_line(center.GetX(),center.GetY(),angle,line_length)
  90 +
  91 + oneside_area, otherside_area = self.jude(polygon, line, angle, line_length)
  92 +
  93 +
  94 + if last_state is None:
  95 +
  96 + angle2 = angle
  97 +
  98 + if oneside_area == 0 and otherside_area==0:
  99 + last_state = 0
  100 + else:
  101 + last_state = 1 if oneside_area < otherside_area else -1
  102 + else:
  103 +
  104 + angle1 = angle2
  105 + angle2 = angle
  106 +
  107 + if oneside_area == 0 and otherside_area==0:
  108 + now_state = 0
  109 + else:
  110 + now_state = 1 if oneside_area < otherside_area else -1
  111 +
  112 + if last_state* now_state < 0:
  113 + # print(angle)
  114 + break
  115 + else:
  116 + last_state = now_state
  117 +
  118 + line = self.division(polygon, center, in_hole, line_length, angle1, angle2, area_thre)
  119 +
  120 + # 提前return
  121 + if in_hole:
  122 +
  123 + point_intersection: Geometry = line.Intersection(in_hole_line)
  124 + plist = []
  125 + for i in range(point_intersection.GetGeometryCount()):
  126 + pi = point_intersection.GetGeometryRef(i)
  127 + plist.append(pi)
  128 + plist_d = [(pi,center.Distance(pi)) for pi in plist]
  129 + plist_d.sort(key=lambda x:x[1])
  130 +
  131 + nearest_point= plist_d[0][0]
  132 + firt_short_length = short_length/20.0
  133 + radline,other_point = self.get_radline(center.GetX(),center.GetY(),nearest_point.GetX(),nearest_point.GetY(),firt_short_length)
  134 + # print("\"" + other_point.ExportToWkt() + "\",")
  135 +
  136 +
  137 + while not polygon.Contains(other_point):
  138 +
  139 + firt_short_length = firt_short_length / 2
  140 + radline, other_point = self.get_radline(center.GetX(), center.GetY(), nearest_point.GetX(),
  141 + nearest_point.GetY(), firt_short_length)
  142 +
  143 +
  144 +
  145 + return RepresentPoint(other_point,polygon)
  146 +
  147 +
  148 + point_intersection:Geometry = line.Intersection(polygon_line)
  149 + xlist = []
  150 + ylist = []
  151 + plist = []
  152 +
  153 + for i in range(point_intersection.GetGeometryCount()):
  154 + pi = point_intersection.GetGeometryRef(i)
  155 + xlist.append(pi.GetX())
  156 + ylist.append(pi.GetY())
  157 + plist.append(pi)
  158 +
  159 + reprecent_point = [(min(xlist)+max(xlist))/2.0,(min(ylist)+max(ylist))/2.0]
  160 +
  161 + reprecent_point = self.creat_point(reprecent_point)
  162 +
  163 + if not polygon.Contains(reprecent_point):
  164 + plist_d = [(pi,center.Distance(pi)) for pi in plist]
  165 + plist_d.sort(key=lambda x:x[1])
  166 + reprecent_point = self.creat_point(((plist_d[0][0].GetX()+ plist_d[1][0].GetX())/2.0, (plist_d[0][0].GetY()+plist_d[1][0].GetY())/2.0))
  167 +
  168 + # print("\""+reprecent_point.ExportToWkt() + "\",")
  169 +
  170 + rp = RepresentPoint(reprecent_point,polygon)
  171 +
  172 + return rp
  173 +
  174 +
  175 +
  176 +
  177 +
  178 + def get_line(self, x0, y0 , angle, r):
  179 +
  180 + line: Geometry = ogr.Geometry(ogr.wkbLineString)
  181 + line.AddPoint(x0, y0)
  182 + hudu = angle/360.0 * 2 * math.pi
  183 + dx = math.sin(hudu) * r
  184 + dy = math.cos(hudu) * r
  185 + line.AddPoint(x0+dx, y0+dy)
  186 +
  187 + return line
  188 +
  189 + def get_doubleline(self, x0, y0 , angle, r):
  190 +
  191 + line: Geometry = ogr.Geometry(ogr.wkbLineString)
  192 +
  193 + hudu = angle/360.0 * 2 * math.pi
  194 + dx = math.sin(hudu) * r
  195 + dy = math.cos(hudu) * r
  196 +
  197 + hudu = (angle+180)/360.0 * 2 * math.pi
  198 + dx2 = math.sin(hudu) * r
  199 + dy2 = math.cos(hudu) * r
  200 +
  201 + line.AddPoint(x0 + dx2, y0 + dy2)
  202 + line.AddPoint(x0+dx, y0+dy)
  203 +
  204 + return line
  205 +
  206 +
  207 + def get_radline(self,x0,y0,x1,y1,len_size):
  208 + a2 = math.pow((x1-x0),2)
  209 + b2 = math.pow((y1-y0),2)
  210 + len_size = len_size+ math.sqrt(a2+b2)
  211 +
  212 + line: Geometry = ogr.Geometry(ogr.wkbLineString)
  213 + line.AddPoint(x0, y0)
  214 + tanx = abs(y1-y0) / abs(x1-x0)
  215 + cosx = 1 / math.sqrt(1 + tanx *tanx)
  216 + dx = cosx* len_size
  217 + dy = tanx * dx
  218 +
  219 + if x1 == x0:
  220 + x2 = x0
  221 + if y1 > y0 :
  222 + y2 = y0 + abs(dy)
  223 + else:
  224 + y2 = y0 - abs(dy)
  225 + else:
  226 + if x1 < x0:
  227 + x2 = x0 - dx
  228 + else:
  229 + x2 = x0 + dx
  230 +
  231 + if y1 < y0:
  232 + y2 = y0 - dy
  233 + else:
  234 + y2 = y0 + dy
  235 +
  236 + line.AddPoint(x2, y2)
  237 +
  238 + other_point = ogr.Geometry(ogr.wkbPoint)
  239 + other_point.AddPoint(x2, y2)
  240 +
  241 + return line , other_point
  242 +
  243 + def get_direction(self,polygon,center,line_length):
  244 + '''
  245 + 判断旋转方向
  246 + :param polygon:
  247 + :param center:
  248 + :param line_length:
  249 + :return:
  250 + '''
  251 +
  252 + line = self.get_line(center.GetX(),center.GetY(),0,line_length)
  253 +
  254 + oneside_area, otherside_area = self.jude(polygon,line,0,line_length)
  255 +
  256 + if oneside_area == 0 and otherside_area == 0 :
  257 + return range(0, 390, 30)
  258 + else:
  259 + line = self.get_line(center.GetX(), center.GetY(), 10, line_length)
  260 + oneside_area_contrast, otherside_area_contrast = self.jude(polygon, line, 30, line_length)
  261 +
  262 + if oneside_area_contrast == 0 and otherside_area_contrast == 0:
  263 + return range(360, -30, -30)
  264 + else:
  265 + if abs(oneside_area - otherside_area) > abs(oneside_area_contrast - otherside_area_contrast):
  266 + return range(0, 390, 30)
  267 + else:
  268 + return range(360, -30, -30)
  269 +
  270 +
  271 + def jude(self,polygon,line,angle,line_length):
  272 +
  273 + line_buffer: Geometry = line.Buffer(line_length / self.buffer_threshold)
  274 + clip_geom: Geometry = polygon.Difference(line_buffer)
  275 +
  276 + oneside_area = 0
  277 + otherside_area = 0
  278 +
  279 + gc = clip_geom.GetGeometryCount()
  280 + if gc <= 1:
  281 + oneside_area = 0
  282 + otherside_area = 0
  283 + else:
  284 + triangle1, triangle2 = self.get_side_triangle(line, angle)
  285 +
  286 +
  287 + for gi in range(clip_geom.GetGeometryCount()):
  288 + clip_geom_i: Geometry = clip_geom.GetGeometryRef(gi)
  289 + it = clip_geom_i.Intersection(triangle1)
  290 +
  291 + if clip_geom_i.Intersect(triangle1) and it.Buffer(line_length / self.buffer_threshold).Intersect(
  292 + line_buffer):
  293 + oneside_area += clip_geom_i.GetArea()
  294 + else:
  295 + otherside_area += clip_geom_i.GetArea()
  296 + return oneside_area, otherside_area
  297 +
  298 + def division(self,polygon,center,in_hole,line_length,angle1,angle2,area_thre):
  299 +
  300 + mid_angle = (angle1 + angle2)/2.0
  301 + if in_hole:
  302 + line = self.get_doubleline(center.GetX(), center.GetY(), mid_angle, line_length)
  303 + else:
  304 + line = self.get_line(center.GetX(), center.GetY(), mid_angle, line_length)
  305 +
  306 + one,other = self.jude(polygon,line,mid_angle,line_length)
  307 +
  308 + while abs(one - other) > area_thre:
  309 + if one > other:
  310 + if angle1 > angle2:
  311 + return self.division(polygon, center, in_hole, line_length, angle2, mid_angle, area_thre)
  312 + else:
  313 + return self.division(polygon, center, in_hole, line_length, mid_angle, angle1, area_thre)
  314 + else:
  315 + if angle1 > angle2:
  316 + return self.division(polygon, center, in_hole, line_length, mid_angle, angle1, area_thre)
  317 + else:
  318 + return self.division(polygon, center, in_hole, line_length, angle2, mid_angle, area_thre)
  319 + return line
  320 +
  321 +
  322 + def get_side_triangle(self,line:Geometry,angle):
  323 + '''
  324 + 获取方向三角形
  325 + :param line:
  326 + :param angle:
  327 + :return:
  328 + '''
  329 +
  330 + start = line.GetPoint(0)
  331 + end = line.GetPoint(1)
  332 +
  333 +
  334 + angle_t = angle-30
  335 + hudu = angle_t/360.0 * 2 * math.pi
  336 +
  337 + r = line.Length() / (2*math.cos( math.pi/6))
  338 + dx = math.sin(hudu) * r
  339 + dy = math.cos(hudu) * r
  340 +
  341 +
  342 + ring1 = ogr.Geometry(ogr.wkbLinearRing)
  343 + ring1.AddPoint(start[0], start[1])
  344 + ring1.AddPoint(start[0] + dx, start[1] + dy)
  345 + ring1.AddPoint(end[0], end[1])
  346 + ring1.AddPoint(start[0], start[1])
  347 + triangle1 = ogr.Geometry(ogr.wkbPolygon)
  348 + triangle1.AddGeometry(ring1)
  349 +
  350 +
  351 + angle_t = angle+30
  352 + hudu = angle_t/360.0 * 2 * math.pi
  353 +
  354 + r = line.Length() / (2*math.cos( math.pi/6))
  355 +
  356 + dx = math.sin(hudu) * r
  357 + dy = math.cos(hudu) * r
  358 +
  359 + ring2 = ogr.Geometry(ogr.wkbLinearRing)
  360 + ring2.AddPoint(start[0], start[1])
  361 + ring2.AddPoint(start[0]+dx, start[1]+dy)
  362 + ring2.AddPoint(end[0], end[1])
  363 + ring2.AddPoint(start[0], start[1])
  364 + triangle2 = ogr.Geometry(ogr.wkbPolygon)
  365 + triangle2.AddGeometry(ring2)
  366 +
  367 + return triangle1,triangle2
  368 +
  369 +
  370 + def creat_point(self,tuple):
  371 + p: Geometry = ogr.Geometry(ogr.wkbPoint)
  372 + p.AddPoint(tuple[0], tuple[1])
  373 + return p
  374 +
  375 +
  376 +
  377 +
  378 + def create_delauney(self,rps):
  379 + multipoint: Geometry = ogr.Geometry(ogr.wkbMultiPoint)
  380 +
  381 + rp_dict = {}
  382 + line_set = set()
  383 + delauney_lines = []
  384 +
  385 + for rp in rps:
  386 + multipoint.AddGeometry(rp.point)
  387 +
  388 + rp_dict[rp.point.GetPoint(0).__str__()] = rp
  389 +
  390 + delauney:Geometry = multipoint.DelaunayTriangulation()
  391 +
  392 + for index in range(delauney.GetGeometryCount()):
  393 + triangle = delauney.GetGeometryRef(index)
  394 +
  395 + triangle_line:Geometry = ogr.ForceToLineString(triangle)
  396 +
  397 +
  398 + for pi in range(triangle_line.GetPointCount()-1):
  399 + p = triangle_line.GetPoint(pi)
  400 + p_next = triangle_line.GetPoint(pi+1)
  401 +
  402 + if p[0] < p_next[0]:
  403 + key = "{}{}".format(p.__str__(),p_next.__str__())
  404 + elif p[0] > p_next[0]:
  405 + key = "{}{}".format(p_next.__str__(), p.__str__())
  406 + else:
  407 + if p[1] < p_next[1]:
  408 + key = "{}{}".format(p.__str__(), p_next.__str__())
  409 + else:
  410 + key = "{}{}".format(p_next.__str__(), p.__str__())
  411 +
  412 + if not line_set.__contains__(key):
  413 + line_set.add(key)
  414 + rp1 = rp_dict.get(p.__str__())
  415 + rp2 = rp_dict.get(p_next.__str__())
  416 +
  417 + delauney_line = DelauneyLine(rp1,rp2)
  418 + delauney_lines.append(delauney_line)
  419 +
  420 + return delauney_lines
  421 +
  422 +
  423 +
  424 + def create_min_delauney(self,delauney_lines,rps,polygons):
  425 + '''
  426 + 使用prim算法计算最小生成树
  427 + :param delauney_lines:
  428 + :param polygons:
  429 + :return:
  430 + '''
  431 +
  432 + kv = {}
  433 + rps_set = set(rps)
  434 +
  435 + for delauney_line in delauney_lines:
  436 + if kv.get(delauney_line.rp1):
  437 +
  438 + kv[delauney_line.rp1].add(delauney_line)
  439 + else:
  440 + kv[delauney_line.rp1] = set()
  441 + kv[delauney_line.rp1].add(delauney_line)
  442 +
  443 + if kv.get(delauney_line.rp2):
  444 +
  445 + kv[delauney_line.rp2].add(delauney_line)
  446 + else:
  447 +
  448 + kv[delauney_line.rp2] = set()
  449 + kv[delauney_line.rp2].add(delauney_line)
  450 +
  451 +
  452 + #初始化树
  453 + delauney_lines = sorted(delauney_lines,key=lambda x:x.distance)
  454 +
  455 +
  456 + delauney_min_tree = DelauneyMinTree()
  457 + delauney_min_tree.append(delauney_lines[0])
  458 +
  459 + rps_set.remove(delauney_lines[0].rp1)
  460 + rps_set.remove(delauney_lines[0].rp2)
  461 + kv[delauney_lines[0].rp1].remove(delauney_lines[0])
  462 + kv[delauney_lines[0].rp2].remove(delauney_lines[0])
  463 +
  464 +
  465 + while rps_set.__len__()>0:
  466 +
  467 + relate_delauney_line = delauney_min_tree.get_other_relate_delauney_lines(kv)
  468 +
  469 + relate_delauney_line_sort = sorted(relate_delauney_line,key=lambda x:x.distance)
  470 +
  471 + min_distance_line = relate_delauney_line_sort[0]
  472 +
  473 + #删除
  474 + other_rp = delauney_min_tree.get_other_rp(min_distance_line)
  475 + if other_rp is None:
  476 + kv[min_distance_line.rp1].remove(min_distance_line)
  477 + kv[min_distance_line.rp2].remove(min_distance_line)
  478 + continue
  479 +
  480 + delauney_min_tree.append(min_distance_line)
  481 +
  482 + rps_set.remove(other_rp)
  483 +
  484 + kv[min_distance_line.rp1].remove(min_distance_line)
  485 + kv[min_distance_line.rp2].remove(min_distance_line)
  486 +
  487 +
  488 +
  489 + for l in delauney_min_tree.delauney_lines_list:
  490 + line = l.line
  491 + # print("\"" + line.ExportToWkt() + "\",")
  492 +
  493 + # print(delauney_min_tree.delauney_lines_list.__len__())
  494 +
  495 + return delauney_min_tree
  496 +
  497 + def cut_delauney_min_tree(self,delauney_min_tree:DelauneyMinTree,threshold):
  498 +
  499 + trees = []
  500 + kv = {}
  501 +
  502 + count = 0
  503 +
  504 + for delauney_line in delauney_min_tree.delauney_lines_list:
  505 +
  506 + dn1 = kv.get(delauney_line.rp1)
  507 + dn2 = kv.get(delauney_line.rp2)
  508 +
  509 +
  510 + if not dn1:
  511 + dn1 = DelauneyNode(delauney_line.rp1)
  512 + kv[delauney_line.rp1] = dn1
  513 +
  514 + if not dn2:
  515 +
  516 + trees.append(dn1)
  517 +
  518 + dn2 = DelauneyNode(delauney_line.rp2)
  519 + kv[delauney_line.rp2] = dn2
  520 +
  521 + if delauney_line.distance < threshold:
  522 + dn1.add_children(dn2,delauney_line)
  523 + count +=1
  524 +
  525 + else:
  526 + #断开
  527 + trees.append(dn2)
  528 + else:
  529 +
  530 + if delauney_line.distance < threshold:
  531 + dn2.add_children(dn1,delauney_line)
  532 + count += 1
  533 + else:
  534 + trees.append(dn1)
  535 + else:
  536 +
  537 + dn2 = DelauneyNode(delauney_line.rp2)
  538 + kv[delauney_line.rp2] = dn2
  539 +
  540 + if delauney_line.distance < threshold:
  541 + dn1.add_children(dn2,delauney_line)
  542 + count += 1
  543 + else:
  544 + trees.append(dn2)
  545 +
  546 +
  547 + return trees
  548 +
  549 + def merge(self,trees):
  550 +
  551 + polygons = []
  552 + for tree in trees:
  553 +
  554 + merge_polygon_raw = list()
  555 +
  556 + dls = tree.get_delauney_lines()
  557 + for dl in dls:
  558 + p1 = dl.rp1.polygon
  559 + p2 = dl.rp2.polygon
  560 +
  561 + merge_polygon_raw.append(p1)
  562 + merge_polygon_raw.append(p2)
  563 + line = dl.line
  564 +
  565 + p1_lines = self.get_polygon_lines(p1)
  566 + p2_lines = self.get_polygon_lines(p2)
  567 +
  568 + p1_intersect_lines = [l for l in p1_lines if l.Intersect(line)]
  569 + p2_intersect_lines = [l for l in p2_lines if l.Intersect(line)]
  570 +
  571 + if p1_intersect_lines.__len__()>1:
  572 + p1_intersect_lines = sorted(p1_intersect_lines,key=lambda x:p2.Distance(x))
  573 + p1_intersect_line_rep = p1_intersect_lines[0]
  574 + elif p1_intersect_lines.__len__()==1:
  575 + p1_intersect_line_rep = p1_intersect_lines[0]
  576 + else:
  577 + continue
  578 +
  579 +
  580 + if p2_intersect_lines.__len__()>1:
  581 + p2_intersect_lines = sorted(p2_intersect_lines,key=lambda x:p1.Distance(x))
  582 + p2_intersect_line_rep = p2_intersect_lines[0]
  583 + elif p2_intersect_lines.__len__()==1:
  584 + p2_intersect_line_rep = p2_intersect_lines[0]
  585 + else:
  586 + continue
  587 +
  588 +
  589 + # #两条线没有距离跳过
  590 + # if p2_intersect_line_rep.Distance(p1_intersect_line_rep) == 0:
  591 + # continue
  592 + # else:
  593 +
  594 + mid_polygon = self.create_mid_polygon(p1_intersect_line_rep,p2_intersect_line_rep,p1,p2)
  595 +
  596 + if mid_polygon.GetArea() > 0.0002116361000058077*0.0002116361000058077:
  597 + continue
  598 +
  599 + merge_polygon_raw.append(mid_polygon)
  600 +
  601 + merge_polygon = None
  602 + for p in merge_polygon_raw:
  603 + if merge_polygon is None:
  604 + merge_polygon = p
  605 + else:
  606 + merge_polygon = merge_polygon.Union(p)
  607 +
  608 + polygons.append(merge_polygon)
  609 +
  610 +
  611 + return polygons
  612 +
  613 +
  614 + def merge2(self,trees):
  615 +
  616 + polygons = []
  617 +
  618 +
  619 +
  620 +
  621 + for tree in trees:
  622 +
  623 + tree_polygons = tree.get_polygons()
  624 +
  625 + points = []
  626 + for p in tree_polygons:
  627 +
  628 + if p.GetGeometryCount() == 1:
  629 + polygon_line: Geometry = ogr.ForceToLineString(p)
  630 +
  631 + polygon_line.Con
  632 + # 有孔Polygon
  633 + else:
  634 + polygon_line: Geometry = ogr.ForceToLineString(p.GetGeometryRef(0))
  635 +
  636 + points.extend(polygon_line.GetPoints()[:-1])
  637 +
  638 + multipoint: Geometry = ogr.Geometry(ogr.wkbMultiPoint)
  639 +
  640 + for p in points:
  641 + poi = ogr.Geometry(ogr.wkbPoint)
  642 + poi.AddPoint(p[0],p[1])
  643 + multipoint.AddGeometry(poi)
  644 +
  645 + delauney: Geometry = multipoint.DelaunayTriangulation()
  646 + merge_polygon = None
  647 +
  648 + for p in delauney:
  649 + # if multi_polygon.Contains(p):
  650 + # continue
  651 +
  652 + pline:Geometry = ogr.ForceToLineString(p)
  653 + pline :list = pline.GetPoints()
  654 + pline.append(pline[1])
  655 +
  656 +
  657 + pass_or_not = False
  658 + for indx in range(3):
  659 + p1 = pline[indx]
  660 + p2 = pline[indx+1]
  661 +
  662 + ppline:Geometry = ogr.Geometry(ogr.wkbLineString)
  663 + ppline.AddPoint(p1[0],p1[1])
  664 + ppline.AddPoint(p2[0], p2[1])
  665 +
  666 +
  667 +
  668 + p3:Geometry = ogr.Geometry(ogr.wkbPoint)
  669 + p3.AddPoint(pline[indx+2][0], pline[indx+2][1])
  670 +
  671 + if p3.Distance(ppline) > 0.0002116361000058077 or ppline.Length() > 0.0002116361000058077:
  672 + pass_or_not = True
  673 + break
  674 +
  675 + if pass_or_not:
  676 + continue
  677 +
  678 + if merge_polygon is None:
  679 + merge_polygon = p
  680 + else:
  681 + merge_polygon = merge_polygon.Union(p)
  682 +
  683 +
  684 +
  685 + polygons.append(merge_polygon)
  686 +
  687 +
  688 + return polygons
  689 +
  690 + def merge_circle(self):
  691 + pass
  692 +
  693 +
  694 + def create_mid_polygon(self,p1_intersect_line_rep,p2_intersect_line_rep,p1,p2):
  695 + '''
  696 + 创建衔接polygon
  697 + :param line:
  698 + :return:
  699 + '''
  700 +
  701 + if p1_intersect_line_rep.Intersect(p2_intersect_line_rep):
  702 +
  703 + p1_rep_p1 = p1_intersect_line_rep.GetPoints()[0]
  704 + p1_rep_p2 = p1_intersect_line_rep.GetPoints()[1]
  705 +
  706 + p2_rep_p1 = p2_intersect_line_rep.GetPoints()[0]
  707 + p2_rep_p2 = p2_intersect_line_rep.GetPoints()[1]
  708 +
  709 + polygon = self.create_polygon(p1_rep_p1, p2_rep_p2, p1_rep_p2, p2_rep_p1)
  710 +
  711 + else:
  712 +
  713 + p1_rep_p1 = p1_intersect_line_rep.GetPoints()[0]
  714 + p1_rep_p2 = p1_intersect_line_rep.GetPoints()[1]
  715 +
  716 + p2_rep_p1 = p2_intersect_line_rep.GetPoints()[0]
  717 + p2_rep_p2 = p2_intersect_line_rep.GetPoints()[1]
  718 +
  719 + line1 = ogr.Geometry(ogr.wkbLineString)
  720 +
  721 +
  722 + line1.AddPoint(p1_rep_p1[0], p1_rep_p1[1])
  723 + line1.AddPoint(p2_rep_p1[0], p2_rep_p1[1])
  724 +
  725 + line2 = ogr.Geometry(ogr.wkbLineString)
  726 + line2.AddPoint(p1_rep_p2[0], p1_rep_p2[1])
  727 + line2.AddPoint(p2_rep_p2[0], p2_rep_p2[1])
  728 +
  729 + if line1.Intersect(line2):
  730 + polygon = self.create_polygon(p1_rep_p1, p1_rep_p2, p2_rep_p1, p2_rep_p2)
  731 + else:
  732 +
  733 + polygon = self.create_polygon(p1_rep_p1, p1_rep_p2, p2_rep_p2, p2_rep_p1)
  734 + if polygon.Intersect(p1) or polygon.Intersect(p2):
  735 + polygon = self.create_polygon(p1_rep_p1, p1_rep_p2, p2_rep_p1, p2_rep_p2)
  736 +
  737 +
  738 + return polygon
  739 +
  740 + def create_polygon(self,p1,p2,p3,p4):
  741 +
  742 + ring = ogr.Geometry(ogr.wkbLinearRing)
  743 + ring.AddPoint(p1[0], p1[1])
  744 + ring.AddPoint(p2[0], p2[1])
  745 + ring.AddPoint(p3[0], p3[1])
  746 + ring.AddPoint(p4[0], p4[1])
  747 + ring.AddPoint(p1[0], p1[1])
  748 +
  749 + poly = ogr.Geometry(ogr.wkbPolygon)
  750 + poly.AddGeometry(ring)
  751 + return poly
  752 +
  753 +
  754 + def get_polygon_lines(self,polygon):
  755 + #无孔Polygon
  756 + if polygon.GetGeometryCount() == 1:
  757 + polygon_line : Geometry = ogr.ForceToLineString(polygon)
  758 + # 有孔Polygon
  759 + else:
  760 + polygon_line : Geometry = ogr.ForceToLineString(polygon.GetGeometryRef(0))
  761 +
  762 + points = polygon_line.GetPoints()
  763 +
  764 + lines = []
  765 + for index in range(len(points)-1):
  766 +
  767 + point_start = points[index]
  768 + point_end = points[index+1]
  769 + line = ogr.Geometry(ogr.wkbLineString)
  770 + line.AddPoint(point_start[0], point_start[1])
  771 + line.AddPoint(point_end[0], point_end[1])
  772 +
  773 + lines.append(line)
  774 +
  775 + return lines
  776 +
  777 + def process(self):
  778 + polygons = self.data.get_polygons()
  779 + rps = []
  780 + for poly in polygons:
  781 + rp = self.get_polygon_reprecent_point(poly)
  782 + rps.append(rp)
  783 +
  784 + delauney_lines = self.create_delauney(rps)
  785 +
  786 + min_delauney = self.create_min_delauney(delauney_lines,rps,polygons)
  787 +
  788 + trees = self.cut_delauney_min_tree(min_delauney,self.distance_buffer_threshold)
  789 +
  790 +
  791 + polygons = self.merge(trees)
  792 +
  793 + for polygon in polygons:
  794 + print("\""+polygon.ExportToWkt() + "\",")
  795 +
  796 +if __name__ == '__main__':
  797 +
  798 +
  799 + # print(sd.get_polygons()[0])
  800 + # sd.close()
  801 +
  802 + create = True
  803 + create = False
  804 +
  805 + if create:
  806 +
  807 + sd = ShapeData(r"J:\Data\制图综合\example.shp")
  808 +
  809 + ext = sd.layer.GetExtent()
  810 + threshold = (ext[1]-ext[0])/20
  811 + print(threshold)
  812 +
  813 +
  814 + zh = Zonghe(sd)
  815 + zh.process()
  816 + else:
  817 + wkts = [
  818 + ]
  819 +
  820 + result = r"J:\Data\制图综合\zhonghe3.shp"
  821 + ShapeData.create_shp_fromwkts(result,"zh",wkts)
  822 +
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/15
  4 +#email: nheweijun@sina.com
... ...
  1 +#!/bin/env python
  2 +
  3 +##
  4 +## determine if two line segments intersect
  5 +## see: martin-thoma.com/how-to-check-if-two-line-segments-intersect/
  6 +##
  7 +
  8 +import numpy as np
  9 +
  10 +def doBoundingBoxesIntersect(a, b, c, d):
  11 + '''
  12 + Check if bounding boxes do intersect. If one bounding box touches
  13 + the other, they do intersect.
  14 + First segment is of points a and b, second of c and d.
  15 + '''
  16 + ll1_x = min(a[0],b[0]); ll2_x = min(c[0],d[0])
  17 + ll1_y = min(a[1],b[1]); ll2_y = min(c[1],d[1])
  18 + ur1_x = max(a[0],b[0]); ur2_x = max(c[0],d[0])
  19 + ur1_y = max(a[1],b[1]); ur2_y = max(c[1],d[1])
  20 +
  21 + return ll1_x <= ur2_x and \
  22 + ur1_x >= ll2_x and \
  23 + ll1_y <= ur2_y and \
  24 + ur1_y >= ll2_y
  25 +
  26 +def isPointOnLine(a,b,c):
  27 + '''
  28 + Check if a point is on a line.
  29 + '''
  30 + # move to origin
  31 + aTmp = (0,0)
  32 + bTmp = (b[0] - a[0], b[1] - a[1])
  33 + cTmp = (c[0] - a[0], c[1] - a[1])
  34 + r = np.cross(bTmp, cTmp)
  35 + return np.abs(r) < 0.0000000001
  36 +
  37 +def isPointRightOfLine(a,b,c):
  38 + '''
  39 + Check if a point (c) is right of a line (a-b).
  40 + If (c) is on the line, it is not right it.
  41 + '''
  42 + # move to origin
  43 + aTmp = (0,0)
  44 + bTmp = (b[0] - a[0], b[1] - a[1])
  45 + cTmp = (c[0] - a[0], c[1] - a[1])
  46 + return np.cross(bTmp, cTmp) < 0
  47 +
  48 +def lineSegmentTouchesOrCrossesLine(a,b,c,d):
  49 + '''
  50 + Check if line segment (a-b) touches or crosses
  51 + line segment (c-d).
  52 + '''
  53 + return isPointOnLine(a,b,c) or \
  54 + isPointOnLine(a,b,d) or \
  55 + (isPointRightOfLine(a,b,c) ^
  56 + isPointRightOfLine(a,b,d))
  57 +
  58 +def doLinesIntersect(a,b,c,d):
  59 + '''
  60 + Check if line segments (a-b) and (c-d) intersect.
  61 + '''
  62 + return doBoundingBoxesIntersect(a,b,c,d) and \
  63 + lineSegmentTouchesOrCrossesLine(a,b,c,d) and \
  64 + lineSegmentTouchesOrCrossesLine(c,d,a,b)
  65 +
  66 +
  67 +##############################
  68 +## Tests
  69 +##############################
  70 +
  71 +def test_doBoundingBoxesIntersect():
  72 + A=(1,1); B=(2,2); C=(3,1); D=(4,2)
  73 + assert doBoundingBoxesIntersect(A,B,C,D) == False
  74 + A=(1,2); B=(3,4); C=(2,1); D=(4,3)
  75 + assert doBoundingBoxesIntersect(A,B,C,D) == True
  76 +
  77 +def test_isPointOnLine():
  78 + A=(1,1); B=(3,3); C=(2,2)
  79 + assert isPointOnLine(A,B,C) == True
  80 + A=(1,1); B=(3,3); C=(3,2)
  81 + assert isPointOnLine(A,B,C) == False
  82 +
  83 +
  84 +def test_isPointRightOfLine():
  85 + A=(1,1); B=(3,3); C=(2,2)
  86 + assert isPointRightOfLine(A,B,C) == False
  87 + A=(1,1); B=(3,3); C=(3,2)
  88 + assert isPointRightOfLine(A,B,C) == True
  89 + A=(1,1); B=(3,3); C=(1,2)
  90 + assert isPointRightOfLine(A,B,C) == False
  91 +
  92 +# a lot of testcases to be tested with the final function
  93 +
  94 +def tcase(name):
  95 + if name == 'F1':
  96 + return (0,0), (7,7), (3,4), (4,5), False
  97 + elif name == 'F2':
  98 + return (-4,4), (-2,1), (-2,3), (0,0), False
  99 + elif name == 'F3':
  100 + return (0,0), (0,1), (2,2), (2,3), False
  101 + elif name == 'F4':
  102 + return (0,0), (0,1), (2,2), (3,2), False
  103 + elif name == 'F5':
  104 + return (-1,-1), (2,2), (3,3), (5,5), False
  105 + elif name == 'F6':
  106 + return (0,0), (1,1), (2,0), (0.5,2), False
  107 + elif name == 'F7':
  108 + return (1,1), (4,1), (2,2), (3,2), False
  109 + elif name == 'F8':
  110 + return (0,5), (6,0), (2,1), (2,2), False
  111 + elif name == 'T1':
  112 + return (0,-2), (0,2), (-2,0), (2,0), True
  113 + elif name == 'T2':
  114 + return (5,5), (0,0), (1,1), (8,2), True
  115 + elif name == 'T3':
  116 + return (-1,0), (0,0), (-1,-1), (-1,1), True
  117 + elif name == 'T4':
  118 + return (0,2), (2,2), (2,0), (2,4), True
  119 + elif name == 'T5':
  120 + return (0,0), (5,5), (1,1), (3,3), True
  121 + elif name == 'T6':
  122 + return (0,0), (3,3), (0,0), (3,3), True
  123 +
  124 +cases = ['F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8',
  125 + 'T1', 'T2', 'T3', 'T4', 'T5', 'T6']
  126 +
  127 +def check_intersection(name):
  128 + A,B,C,D, result = tcase(name)
  129 + assert doLinesIntersect(A,B,C,D) == result
  130 +
  131 +def test_doLinesIntersect():
  132 + for case in cases:
  133 + yield check_intersection, case
  134 +
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2022/3/8
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from osgeo import ogr
  8 +from osgeo.ogr import *
  9 +import math
  10 +import os
  11 +import copy
  12 +os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
  13 +
  14 +from test.zonghe.ShapeData import ShapeData
  15 +from test.zonghe.ConcaveHull import concaveHull
  16 +import numpy as np
  17 +
  18 +class Zonghe:
  19 +
  20 + data:ShapeData
  21 + area_threshold = 100.0
  22 + buffer_threshold = 100.0
  23 + distance_buffer_threshold = 2.114691025217302e-04
  24 +
  25 + def __init__(self,data):
  26 + self.data = data
  27 +
  28 +
  29 + def creat_point(self,tuple):
  30 + p: Geometry = ogr.Geometry(ogr.wkbPoint)
  31 + p.AddPoint(tuple[0], tuple[1])
  32 + return p
  33 +
  34 +
  35 +
  36 + def merge2(self,p1,p2):
  37 +
  38 + polygons = []
  39 + points = []
  40 +
  41 + for p in [p1,p2]:
  42 +
  43 + if p.GetGeometryCount() == 1:
  44 + polygon_line: Geometry = ogr.ForceToLineString(p)
  45 + # 有孔Polygon
  46 + else:
  47 + polygon_line: Geometry = ogr.ForceToLineString(p.GetGeometryRef(0))
  48 +
  49 + points.extend(polygon_line.GetPoints()[:-1])
  50 +
  51 + multipoint: Geometry = ogr.Geometry(ogr.wkbMultiPoint)
  52 +
  53 +
  54 + for p in points:
  55 + poi = ogr.Geometry(ogr.wkbPoint)
  56 + poi.AddPoint(p[0],p[1])
  57 + multipoint.AddGeometry(poi)
  58 +
  59 + delauney: Geometry = multipoint.DelaunayTriangulation()
  60 + merge_polygon = None
  61 +
  62 + for p in delauney:
  63 +
  64 + p_c = p.Centroid()
  65 +
  66 + # print("\"" + p_c.ExportToWkt() + "\",")
  67 + if p1.Contains(p) or p2.Contains(p):
  68 + continue
  69 + print("\"" + p.ExportToWkt() + "\",")
  70 +
  71 +
  72 + return polygons
  73 +
  74 +
  75 + def merge(self,p1,p2):
  76 +
  77 +
  78 +
  79 + if p1.GetGeometryCount() == 1:
  80 + polygon_line1: Geometry = ogr.ForceToLineString(p1)
  81 + # 有孔Polygon
  82 + else:
  83 + polygon_line1: Geometry = ogr.ForceToLineString(p1.GetGeometryRef(0))
  84 +
  85 +
  86 + p1_points = polygon_line1.GetPoints()[:-1]
  87 +
  88 + if p2.GetGeometryCount() == 1:
  89 + polygon_line2: Geometry = ogr.ForceToLineString(p2)
  90 + # 有孔Polygon
  91 + else:
  92 + polygon_line2: Geometry = ogr.ForceToLineString(p2.GetGeometryRef(0))
  93 +
  94 + p2_points = polygon_line2.GetPoints()[:-1]
  95 +
  96 +
  97 + multipoint: Geometry = ogr.Geometry(ogr.wkbMultiPoint)
  98 +
  99 +
  100 +
  101 +
  102 + for p in p1_points:
  103 +
  104 + p_t = False
  105 + for pp in p2_points:
  106 + line = ogr.Geometry(ogr.wkbLineString)
  107 + line.AddPoint(p[0], p[1])
  108 + line.AddPoint(pp[0], pp[1])
  109 +
  110 + ggg:Geometry = line.Intersection(p1)
  111 +
  112 +
  113 + if ggg.GetGeometryType() in [1,-2147483647,3001]:
  114 + p_t = True
  115 + break
  116 + if p_t:
  117 + pppp = ogr.Geometry(ogr.wkbPoint)
  118 + pppp.AddPoint(p[0],p[1])
  119 +
  120 + multipoint.AddGeometry(pppp)
  121 +
  122 + for p in p2_points:
  123 +
  124 + p_t = False
  125 + for pp in p1_points:
  126 + line = ogr.Geometry(ogr.wkbLineString)
  127 + line.AddPoint(p[0], p[1])
  128 + line.AddPoint(pp[0], pp[1])
  129 +
  130 + ggg:Geometry = line.Intersection(p2)
  131 +
  132 +
  133 + if ggg.GetGeometryType() in [1,-2147483647,3001]:
  134 + p_t = True
  135 + break
  136 + if p_t:
  137 + pppp = ogr.Geometry(ogr.wkbPoint)
  138 + pppp.AddPoint(p[0],p[1])
  139 + multipoint.AddGeometry(pppp)
  140 +
  141 +
  142 + delauney: Geometry = multipoint.DelaunayTriangulation()
  143 + merge_polygon = None
  144 +
  145 + for p in delauney:
  146 +
  147 + print("\"" + p.ExportToWkt() + "\",")
  148 +
  149 +
  150 +
  151 + return None
  152 +
  153 + def merge3(self,polygons):
  154 +
  155 + multi_poly = ogr.Geometry(ogr.wkbMultiPolygon)
  156 +
  157 + points = []
  158 + for poly in polygons:
  159 + multi_poly.AddGeometry(poly)
  160 + if poly.GetGeometryCount() == 1:
  161 + poly_line: Geometry = ogr.ForceToLineString(poly)
  162 + # 有孔Polygon
  163 + else:
  164 + poly_line: Geometry = ogr.ForceToLineString(poly.GetGeometryRef(0))
  165 +
  166 + points.extend(poly_line.GetPoints()[:-1])
  167 +
  168 +
  169 + points = np.array([[p[0],p[1]] for p in points])
  170 +
  171 + merge_p_line = concaveHull(points, 3)
  172 +
  173 + ring = ogr.Geometry(ogr.wkbLinearRing)
  174 +
  175 + merge_p = ogr.Geometry(ogr.wkbPolygon)
  176 +
  177 +
  178 + for l in merge_p_line:
  179 + ring.AddPoint(l[0], l[1])
  180 +
  181 + ring.AddPoint(merge_p_line[0][0], merge_p_line[0][1])
  182 +
  183 + merge_p.AddGeometry(ring)
  184 +
  185 +
  186 + # for p in polygons:
  187 + #
  188 + # merge_p = merge_p.Union(p)
  189 + #
  190 + #
  191 + #
  192 + # print(merge_p)
  193 +
  194 + return [merge_p.ExportToWkt()]
  195 +
  196 +
  197 +
  198 +
  199 + def merge4(self,p1,p2):
  200 +
  201 + polygons = []
  202 + points = []
  203 +
  204 + mp: Geometry = ogr.Geometry(ogr.wkbMultiPolygon)
  205 + mp.AddGeometry(p1)
  206 + mp.AddGeometry(p2)
  207 +
  208 +
  209 + delauney: Geometry = mp.DelaunayTriangulation(bOnlyEdges=True)
  210 + merge_polygon = None
  211 +
  212 + for p in delauney:
  213 +
  214 + p_c = p.Centroid()
  215 +
  216 + # print("\"" + p_c.ExportToWkt() + "\",")
  217 + # if p1.Contains(p) or p2.Contains(p):
  218 + # continue
  219 + print("\"" + p.ExportToWkt() + "\",")
  220 +
  221 +
  222 + return polygons
  223 +
  224 + def merge5(self,p1:Geometry,p2):
  225 +
  226 +
  227 +
  228 + ext = p1.GetEnvelope()
  229 +
  230 + tor = min(ext[1]-ext[0],ext[3]-ext[2])
  231 +
  232 + pp = p1.Simplify(tor/20)
  233 +
  234 + pp2 = p2.Simplify(tor / 20)
  235 +
  236 + return [pp.ExportToWkt(),pp2.ExportToWkt() ]
  237 +
  238 +
  239 + def process(self):
  240 + polygons = self.data.get_polygons()
  241 +
  242 + return self.merge3(polygons)
  243 +
  244 +
  245 +if __name__ == '__main__':
  246 +
  247 +
  248 + # print(sd.get_polygons()[0])
  249 + # sd.close()
  250 +
  251 + # create = True
  252 + # create = False
  253 + #
  254 + # if create:
  255 + #
  256 + # sd = ShapeData(r"J:\Data\制图综合\me.shp")
  257 + #
  258 + # ext = sd.layer.GetExtent()
  259 + # threshold = (ext[1]-ext[0])/20
  260 + # print(threshold)
  261 + #
  262 + #
  263 + # zh = Zonghe(sd)
  264 + # zh.process()
  265 + # else:
  266 + # wkts = ["POLYGON ((113.371086251 22.5101043861001,113.371311338 22.5099257505,113.371611445 22.5098560668001,113.371450698 22.5095291511,113.370775465 22.5096884259,113.371086251 22.5101043861001))"
  267 + # ]
  268 + # result = r"J:\Data\制图综合\mes.shp"
  269 + # ShapeData.create_shp_fromwkts(result,"zh",wkts)
  270 + #
  271 +
  272 +
  273 + sd = ShapeData(r"J:\Data\制图综合\concave.shp")
  274 +
  275 + ext = sd.layer.GetExtent()
  276 + threshold = (ext[1]-ext[0])/20
  277 + print(threshold)
  278 +
  279 +
  280 + zh = Zonghe(sd)
  281 + wkts = zh.process()
  282 +
  283 +
  284 + result = r"J:\Data\制图综合\concave_merge.shp"
  285 + ShapeData.create_shp_fromwkts(result,"zh",wkts)
  286 +
... ...
... ... @@ -8,6 +8,7 @@ from osgeo import ogr
8 8 from osgeo.ogr import *
9 9 import math
10 10 import os
  11 +import copy
11 12 os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
12 13 class util:
13 14 @classmethod
... ... @@ -24,6 +25,39 @@ class util:
24 25 return poly
25 26
26 27
  28 +class RepresentPoint(Geometry):
  29 + user_data = None
  30 + def SetUserData(self,object):
  31 + self.user_data = object
  32 + def GetUserData(self):
  33 + return self.user_data
  34 +
  35 +class DelauneyNode:
  36 +
  37 + point = None
  38 + node = None
  39 + children_nodes = []
  40 + children_nodes_distance = []
  41 + polygon = None
  42 +
  43 + def __init__(self, point):
  44 + self.point = point
  45 +
  46 + def get_all_node(self):
  47 + for node in self.children_nodes:
  48 + yield node.get_all_node()
  49 + yield self.node
  50 +
  51 +
  52 + def cut_tree(self,threshold):
  53 +
  54 + trees = []
  55 +
  56 + for node in self.children_nodes:
  57 + yield node.get_all_node()
  58 + yield self.node
  59 +
  60 +
27 61 class ShapeUtil:
28 62
29 63 driver = ogr.GetDriverByName("ESRI Shapefile")
... ... @@ -88,7 +122,7 @@ class ShapeData:
88 122
89 123 def __init__(self,path):
90 124 driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
91   - self.ds: DataSource = driver.Open(path, 1)
  125 + self.ds: DataSource = driver.Open(path, 0)
92 126 if not self.ds:
93 127 raise Exception("打开数据失败!")
94 128 self.layer: Layer = self.ds.GetLayer(0)
... ... @@ -99,7 +133,7 @@ class ShapeData:
99 133 polygons = []
100 134 for feature in self.layer:
101 135 f:Feature = feature
102   - geom : Geometry = f.GetGeometryRef()
  136 + geom : Geometry = copy.deepcopy(f.GetGeometryRef())
103 137 if geom.GetGeometryType() == 3 or geom.GetGeometryType() == -2147483645:
104 138 polygons.append(geom)
105 139 if geom.GetGeometryType() == 6 or geom.GetGeometryType() == -2147483642:
... ... @@ -114,7 +148,7 @@ class ShapeData:
114 148 class Zonghe:
115 149
116 150 data:ShapeData
117   - area_threshold = 20.0
  151 + area_threshold = 100.0
118 152 buffer_threshold = 100.0
119 153
120 154 def __init__(self,data):
... ... @@ -127,12 +161,20 @@ class Zonghe:
127 161
128 162 polygon_env = polygon.GetEnvelope()
129 163
130   - line_length = max(polygon_env[1]-polygon_env[0],polygon_env[3]-polygon_env[2])
  164 + area_thre = polygon.GetArea()/self.area_threshold
  165 +
  166 + # line_length = max(polygon_env[1]-polygon_env[0],polygon_env[3]-polygon_env[2])
  167 +
  168 + line_length = math.sqrt(math.pow(polygon_env[1] - polygon_env[0],2) + math.pow(polygon_env[3] - polygon_env[2],2))
131 169
132 170
133 171 short_length = min(polygon_env[1]-polygon_env[0],polygon_env[3]-polygon_env[2])
134 172
  173 +
  174 +
135 175 center:Geometry = polygon.Centroid()
  176 + # print(center)
  177 +
136 178
137 179 # 提前return
138 180 if polygon.Contains(center):
... ... @@ -141,7 +183,10 @@ class Zonghe:
141 183 last_state = None
142 184 line = None
143 185 calculate_time = 0
  186 +
144 187 direction = self.get_direction(polygon, center, line_length)
  188 +
  189 + # print(direction)
145 190 in_hole = False
146 191 in_hole_line = None
147 192
... ... @@ -160,9 +205,9 @@ class Zonghe:
160 205 in_hole = True
161 206 direction = range(0,190,10)
162 207 in_hole_line = ogr.ForceToLineString(hole_line)
163   - print("in_hole")
164   -
  208 + # print("in_hole")
165 209
  210 + angle1,angle2=None,None
166 211
167 212 for angle in direction:
168 213
... ... @@ -171,45 +216,41 @@ class Zonghe:
171 216 else:
172 217 line = self.get_line(center.GetX(),center.GetY(),angle,line_length)
173 218
174   - line_buffer:Geometry = line.Buffer(line_length / self.buffer_threshold)
175   - clip_geom: Geometry = polygon.Difference(line_buffer)
  219 + oneside_area, otherside_area = self.jude(polygon, line, angle, line_length)
  220 + # print(oneside_area, otherside_area)
176 221
177   - oneside_area = 0
178   - otherside_area = 0
  222 + # print("\"" + line.ExportToWkt() + "\",")
179 223
180   - gc = clip_geom.GetGeometryCount()
181   - if gc <= 1:
182   - oneside_area = 0
183   - otherside_area = 0
184   - else:
185   - calculate_time += 1
186   - triangle1, triangle2 = self.get_side_triangle(line, angle)
187   -
188   - for gi in range(clip_geom.GetGeometryCount()):
189   - clip_geom_i :Geometry = clip_geom.GetGeometryRef(gi)
190   - it = clip_geom_i.Intersection(triangle1)
191   -
192   - if clip_geom_i.Intersect(triangle1) and it.Buffer(line_length / self.buffer_threshold).Intersect(line_buffer):
193   - oneside_area += clip_geom_i.GetArea()
194   - else:
195   - otherside_area += clip_geom_i.GetArea()
196   - print(oneside_area,otherside_area)
197 224 if last_state is None:
  225 +
  226 + angle2 = angle
  227 +
198 228 if oneside_area == 0 and otherside_area==0:
199 229 last_state = 0
200 230 else:
201 231 last_state = 1 if oneside_area < otherside_area else -1
202 232 else:
  233 +
  234 + angle1 = angle2
  235 + angle2 = angle
  236 +
203 237 if oneside_area == 0 and otherside_area==0:
204 238 now_state = 0
205 239 else:
206 240 now_state = 1 if oneside_area < otherside_area else -1
207 241
208 242 if last_state* now_state < 0:
  243 + # print(angle)
209 244 break
210 245 else:
211 246 last_state = now_state
212 247
  248 +
  249 + # print("start division")
  250 + # print(angle1, angle2)
  251 +
  252 + line = self.division(polygon, center, in_hole, line_length, angle1, angle2, area_thre)
  253 +
213 254 # 提前return
214 255 if in_hole:
215 256 # print(line)
... ... @@ -232,14 +273,14 @@ class Zonghe:
232 273
233 274 radline,other_point = self.get_radline(center.GetX(),center.GetY(),nearest_point.GetX(),nearest_point.GetY(),firt_short_length)
234 275
235   - print(other_point)
  276 + # print(other_point)
236 277
237 278 while not polygon.Contains(other_point):
238 279 firt_short_length = firt_short_length / 2
239 280 radline, other_point = self.get_radline(center.GetX(), center.GetY(), nearest_point.GetX(),
240 281 nearest_point.GetY(), firt_short_length)
241 282
242   - print("return hole_rep")
  283 + # print("return hole_rep")
243 284
244 285 return other_point
245 286
... ... @@ -264,60 +305,33 @@ class Zonghe:
264 305 plist_d.sort(key=lambda x:x[1])
265 306 reprecent_point = self.creat_point(((plist_d[0][0].GetX()+ plist_d[1][0].GetX())/2.0, (plist_d[0][0].GetY()+plist_d[1][0].GetY())/2.0))
266 307
267   - return reprecent_point
268   -
269   -
270   - def create_delauney(self,polygon:Geometry):
271   - de = polygon.DelaunayTriangulation()
272   -
273   - for i in range(de.GetGeometryCount()):
274   - d:Geometry = de.GetGeometryRef(i)
275   -
276   - print("\""+d.ExportToWkt()+"\",")
277   -
  308 + print(reprecent_point)
278 309
279   - def create_delauney_test(self):
280   -
281   - mp:Geometry = ogr.Geometry(ogr.wkbMultiPoint)
282   -
283   - p1: Geometry = ogr.Geometry(ogr.wkbPoint)
284   - p1.AddPoint(1,1)
285   -
286   - mp.AddGeometry(p1)
287   -
288   - p2: Geometry = ogr.Geometry(ogr.wkbPoint)
289   - p2.AddPoint(1.5, 1.7)
290   -
291   - mp.AddGeometry(p2)
292   -
293   -
294   - p3: Geometry = ogr.Geometry(ogr.wkbPoint)
295   - p3.AddPoint(2, 10)
296   -
297   - mp.AddGeometry(p3)
  310 + return reprecent_point
298 311
299   - p4: Geometry = ogr.Geometry(ogr.wkbPoint)
300   - p4.AddPoint(3, 5)
301   - mp.AddGeometry(p4)
302 312
303   - p5: Geometry = ogr.Geometry(ogr.wkbPoint)
304   - p5.AddPoint(4, 2)
305   - mp.AddGeometry(p5)
  313 + def create_delauney(self,points):
  314 + multipoint: Geometry = ogr.Geometry(ogr.wkbMultiPoint)
  315 + for point in points:
  316 + multipoint.AddGeometry(point)
  317 + delauney = multipoint.DelaunayTriangulation()
306 318
307   - p6: Geometry = ogr.Geometry(ogr.wkbPoint)
308 319
309   - p6.AddPoint(3, 1)
310 320
311   - mp.AddGeometry(p6)
312 321
313   - de = mp.DelaunayTriangulation()
314 322
315   - print(mp)
  323 + # def delauney_min_tree(self,points,delauney):
  324 + # lines = []
  325 + # for i in range(delauney.GetGeometryCount()):
  326 + # triangle:Geometry = delauney.GetGeometryRef(i)
  327 + #
  328 + # triangle_line :Geometry = ogr.ForceToLineString(triangle)
  329 + # triangle_line_points = triangle_line.GetPoints()
  330 + #
  331 + # distance =
  332 + # bian1 = (triangle_line_points[0],triangle_line_points[1],)
316 333
317   - for i in range(de.GetGeometryCount()):
318   - d:Geometry = de.GetGeometryRef(i)
319 334
320   - print("\""+d.ExportToWkt()+"\",")
321 335
322 336 def get_line(self, x0, y0 , angle, r):
323 337
... ... @@ -356,6 +370,8 @@ class Zonghe:
356 370 cosx = 1 / math.sqrt(1 + tanx *tanx)
357 371 dx = cosx* len_size
358 372
  373 +
  374 +
359 375 x2 = x1 + dx
360 376
361 377 if x1 != x0:
... ... @@ -380,17 +396,42 @@ class Zonghe:
380 396 '''
381 397
382 398 line = self.get_line(center.GetX(),center.GetY(),0,line_length)
383   - line_buffer:Geometry = line.Buffer(line_length / self.buffer_threshold)
  399 +
  400 + oneside_area, otherside_area = self.jude(polygon,line,0,line_length)
  401 +
  402 + if oneside_area == 0 and otherside_area == 0 :
  403 + return range(0, 390, 30)
  404 + else:
  405 + line = self.get_line(center.GetX(), center.GetY(), 10, line_length)
  406 + oneside_area_contrast, otherside_area_contrast = self.jude(polygon, line, 30, line_length)
  407 +
  408 + if oneside_area_contrast == 0 and otherside_area_contrast == 0:
  409 + return range(360, -30, -30)
  410 + else:
  411 + if abs(oneside_area - otherside_area) > abs(oneside_area_contrast - otherside_area_contrast):
  412 + return range(0, 390, 30)
  413 + else:
  414 + return range(360, -30, -30)
  415 +
  416 +
  417 + def jude(self,polygon,line,angle,line_length):
  418 +
  419 + line_buffer: Geometry = line.Buffer(line_length / self.buffer_threshold)
384 420 clip_geom: Geometry = polygon.Difference(line_buffer)
385 421
386   - gc = clip_geom.GetGeometryCount()
387 422 oneside_area = 0
388 423 otherside_area = 0
389 424
  425 + gc = clip_geom.GetGeometryCount()
390 426 if gc <= 1:
391   - return range(0,370,10)
  427 + oneside_area = 0
  428 + otherside_area = 0
392 429 else:
393   - triangle1, triangle2 = self.get_side_triangle(line, 0)
  430 + triangle1, triangle2 = self.get_side_triangle(line, angle)
  431 + # print(angle)
  432 + # print(line)
  433 + # print(triangle1)
  434 + # print(triangle2)
394 435
395 436 for gi in range(clip_geom.GetGeometryCount()):
396 437 clip_geom_i: Geometry = clip_geom.GetGeometryRef(gi)
... ... @@ -401,34 +442,35 @@ class Zonghe:
401 442 oneside_area += clip_geom_i.GetArea()
402 443 else:
403 444 otherside_area += clip_geom_i.GetArea()
  445 + return oneside_area, otherside_area
404 446
405   - oneside_area_contrast = 0
406   - otherside_area_contrast = 0
407   -
408   - line = self.get_line(center.GetX(), center.GetY(), 10, line_length)
409   - line_buffer: Geometry = line.Buffer(line_length / self.buffer_threshold)
410   - clip_geom: Geometry = polygon.Difference(line_buffer)
  447 + def division(self,polygon,center,in_hole,line_length,angle1,angle2,area_thre):
411 448
412   - gc = clip_geom.GetGeometryCount()
413   - if gc <= 1:
414   - return range(360, -10, -10)
415   - else:
416   - triangle1, triangle2 = self.get_side_triangle(line, 10)
  449 + mid_angle = (angle1 + angle2)/2.0
  450 + if in_hole:
  451 + line = self.get_doubleline(center.GetX(), center.GetY(), mid_angle, line_length)
  452 + else:
  453 + line = self.get_line(center.GetX(), center.GetY(), mid_angle, line_length)
417 454
418   - for gi in range(clip_geom.GetGeometryCount()):
419   - clip_geom_i: Geometry = clip_geom.GetGeometryRef(gi)
420   - it = clip_geom_i.Intersection(triangle1)
  455 + # print("\""+line.ExportToWkt()+"\",")
421 456
422   - if clip_geom_i.Intersect(triangle1) and it.Buffer(line_length / self.buffer_threshold).Intersect(
423   - line_buffer):
424   - oneside_area_contrast += clip_geom_i.GetArea()
425   - else:
426   - otherside_area_contrast += clip_geom_i.GetArea()
  457 + one,other = self.jude(polygon,line,mid_angle,line_length)
  458 + # print(mid_angle)
  459 + # print(one,other)
427 460
428   - if abs(oneside_area - otherside_area) > abs(oneside_area_contrast - otherside_area_contrast):
429   - return range(0, 370, 10)
  461 + while abs(one - other) > area_thre:
  462 + if one > other:
  463 + if angle1 > angle2:
  464 + return self.division(polygon, center, in_hole, line_length, angle2, mid_angle, area_thre)
430 465 else:
431   - return range(360, -10, -10)
  466 + return self.division(polygon, center, in_hole, line_length, mid_angle, angle1, area_thre)
  467 + else:
  468 + if angle1 > angle2:
  469 + return self.division(polygon, center, in_hole, line_length, mid_angle, angle1, area_thre)
  470 + else:
  471 + return self.division(polygon, center, in_hole, line_length, angle2, mid_angle, area_thre)
  472 + return line
  473 +
432 474
433 475 def get_side_triangle(self,line:Geometry,angle):
434 476 '''
... ... @@ -483,57 +525,63 @@ class Zonghe:
483 525 p.AddPoint(tuple[0], tuple[1])
484 526 return p
485 527
  528 +
  529 + def merge(self,delauney_node:DelauneyNode):
  530 + nodes = delauney_node.get_all_node()
  531 + points = [node.point for node in nodes]
  532 +
  533 + return None
  534 +
  535 +
486 536 def process(self):
487 537 polygons = self.data.get_polygons()
  538 +
  539 + Rps = []
488 540 for poly in polygons:
489 541 reprecent_point = self.get_polygon_reprecent_point(poly)
490   - print(reprecent_point)
  542 +
491 543
492 544
493 545
494 546 if __name__ == '__main__':
495 547
496   - # sd = ShapeData(r"J:\Data\矢量数据\佛山\制图综合.shp")
  548 +
497 549 # print(sd.get_polygons()[0])
498 550 # sd.close()
499 551
500 552 create = True
501   - create = False
  553 + # create = False
502 554
503 555 if create:
504 556
505   - driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
506   - ds: DataSource = driver.Open(r"J:\Data\制图综合\t1.shp",0)
507   -
508   - layer: Layer = ds.GetLayer(0)
509   -
510   - polygons = []
511   - for feature in layer:
512   - f:Feature = feature
513   - geom : Geometry = f.GetGeometryRef()
514   - if geom.GetGeometryType() == 3 or geom.GetGeometryType() == -2147483645:
515   - polygons.append(geom)
516   - if geom.GetGeometryType() == 6 or geom.GetGeometryType() == -2147483642:
517   - for i in range(geom.GetGeometryCount()):
518   - polygons.append(geom.GetGeometryRef(i))
519   - del ds
520   - zh = Zonghe("d")
521   - pre = zh.get_polygon_reprecent_point(polygons[0])
  557 + # driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
  558 + # ds: DataSource = driver.Open(r"J:\Data\制图综合\left.shp",0)
  559 + #
  560 + # layer: Layer = ds.GetLayer(0)
  561 + #
  562 + # polygons = []
  563 + # for feature in layer:
  564 + # f:Feature = feature
  565 + # geom : Geometry = f.GetGeometryRef()
  566 + # if geom.GetGeometryType() == 3 or geom.GetGeometryType() == -2147483645:
  567 + # polygons.append(geom)
  568 + # if geom.GetGeometryType() == 6 or geom.GetGeometryType() == -2147483642:
  569 + # for i in range(geom.GetGeometryCount()):
  570 + # polygons.append(geom.GetGeometryRef(i))
  571 + # del ds
522 572
  573 + sd = ShapeData(r"J:\Data\制图综合\t5.shp")
  574 + zh = Zonghe(sd)
  575 + zh.process()
523 576
524 577
525   - zh.create_delauney_test()
526   -
527 578
528 579 else:
529 580
530 581
531   - wkts = ["POLYGON ((2 10 0,1 1 0,1.5 1.7 0,2 10 0))",
532   -"POLYGON ((2 10 0,1.5 1.7 0,3 5 0,2 10 0))",
533   -"POLYGON ((2 10 0,3 5 0,4 2 0,2 10 0))",
534   -"POLYGON ((3 1 0,4 2 0,1.5 1.7 0,3 1 0))",
535   -"POLYGON ((3 1 0,1.5 1.7 0,1 1 0,3 1 0))",
536   -"POLYGON ((1.5 1.7 0,4 2 0,3 5 0,1.5 1.7 0))",]
537   - result = r"J:\Data\制图综合\mpde.shp"
  582 + wkts = ["POINT (113.211177054031 22.8681300466504)"
  583 + ]
  584 +
  585 + result = r"J:\Data\制图综合\left_center.shp"
538 586 ShapeUtil.create_shp_fromwkts(result,"zh",wkts)
539 587
... ...
注册登录 后发表评论