提交 437d3cc6a29f9b4301d5737fb09f494d5f8030d6

作者 nheweijun
1 个父辈 5956d01d

2022.03.22 修改模块回调问题

@@ -6,8 +6,10 @@ from app.util.component.ParameterUtil import ParameterUtil @@ -6,8 +6,10 @@ from app.util.component.ParameterUtil import ParameterUtil
6 from flask import current_app,request 6 from flask import current_app,request
7 import traceback 7 import traceback
8 import json 8 import json
9 -from app.modules.auth.models import OAuth2Token,User,db 9 +from app.models import db
  10 +from app.modules.auth.models import OAuth2Token,User
10 import app 11 import app
  12 +
11 class ApiTemplate: 13 class ApiTemplate:
12 #模板方法 14 #模板方法
13 para = dict() 15 para = dict()
@@ -28,10 +30,11 @@ class ApiTemplate: @@ -28,10 +30,11 @@ class ApiTemplate:
28 if app.GLOBAL_DIC.get(token): 30 if app.GLOBAL_DIC.get(token):
29 self.para["creator"] = app.GLOBAL_DIC.get(token) 31 self.para["creator"] = app.GLOBAL_DIC.get(token)
30 else: 32 else:
31 - user = User.query.join(OAuth2Token).filter(OAuth2Token.access_token == token).one_or_none()  
32 - if user:  
33 - self.para["creator"] = user.username  
34 - app.GLOBAL_DIC[token] = user.username 33 + sql = "select username from dmap_user join dmap_oauth2_token on dmap_user.id=dmap_oauth2_token.user_id where dmap_oauth2_token.access_token='{}'".format(token)
  34 + result = db.session.execute(sql).fetchone()
  35 + if result:
  36 + self.para["creator"] = result[0]
  37 + app.GLOBAL_DIC[token] = result[0]
35 38
36 def para_check(self): 39 def para_check(self):
37 pass 40 pass
  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 +from test.zonghe.ConcaveHull import concaveHull
  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 +import numpy as np
  20 +
  21 +class Zonghe:
  22 +
  23 + data:ShapeData
  24 + area_threshold = 100.0
  25 + buffer_threshold = 100.0
  26 + distance_buffer_threshold = 1.114691025217302e-04
  27 +
  28 + def __init__(self,data):
  29 + self.data = data
  30 +
  31 +
  32 + #只处理Polygon,MultiPolygon要拆开
  33 + def get_polygon_reprecent_point(self,polygon:Geometry):
  34 +
  35 + polygon_env = polygon.GetEnvelope()
  36 +
  37 + area_thre = polygon.GetArea()/self.area_threshold
  38 +
  39 + line_length = math.sqrt(math.pow(polygon_env[1] - polygon_env[0],2) + math.pow(polygon_env[3] - polygon_env[2],2))
  40 +
  41 +
  42 + short_length = min(polygon_env[1]-polygon_env[0],polygon_env[3]-polygon_env[2])
  43 +
  44 +
  45 +
  46 + center:Geometry = polygon.Centroid()
  47 + # print(center)
  48 +
  49 +
  50 + # 提前return
  51 + if polygon.Contains(center):
  52 + # print("\"" + center.ExportToWkt() + "\",")
  53 + return RepresentPoint(center, polygon)
  54 +
  55 +
  56 + last_state = None
  57 + line = None
  58 + calculate_time = 0
  59 +
  60 + direction = self.get_direction(polygon, center, line_length)
  61 +
  62 +
  63 + in_hole = False
  64 + in_hole_line = None
  65 +
  66 +
  67 + #无孔Polygon
  68 + if polygon.GetGeometryCount() == 1:
  69 + polygon_line = ogr.ForceToLineString(polygon)
  70 +
  71 + # 有孔Polygon,要分2种情况
  72 + else:
  73 + polygon_line = ogr.ForceToLineString(polygon.GetGeometryRef(0))
  74 + for i in range(1,polygon.GetGeometryCount()):
  75 + hole_line = polygon.GetGeometryRef(i)
  76 + hole_polygon : Geometry = ogr.ForceToPolygon(hole_line)
  77 + if hole_polygon.Contains(center):
  78 + in_hole = True
  79 + direction = range(0,190,10)
  80 + in_hole_line = ogr.ForceToLineString(hole_line)
  81 + # print("in_hole")
  82 +
  83 + angle1,angle2=None,None
  84 +
  85 + for angle in direction:
  86 +
  87 + if in_hole:
  88 + line = self.get_doubleline(center.GetX(),center.GetY(),angle,line_length)
  89 + else:
  90 + line = self.get_line(center.GetX(),center.GetY(),angle,line_length)
  91 +
  92 + oneside_area, otherside_area = self.jude(polygon, line, angle, line_length)
  93 +
  94 +
  95 + if last_state is None:
  96 +
  97 + angle2 = angle
  98 +
  99 + if oneside_area == 0 and otherside_area==0:
  100 + last_state = 0
  101 + else:
  102 + last_state = 1 if oneside_area < otherside_area else -1
  103 + else:
  104 +
  105 + angle1 = angle2
  106 + angle2 = angle
  107 +
  108 + if oneside_area == 0 and otherside_area==0:
  109 + now_state = 0
  110 + else:
  111 + now_state = 1 if oneside_area < otherside_area else -1
  112 +
  113 + if last_state* now_state < 0:
  114 + # print(angle)
  115 + break
  116 + else:
  117 + last_state = now_state
  118 +
  119 + line = self.division(polygon, center, in_hole, line_length, angle1, angle2, area_thre)
  120 +
  121 + # 提前return
  122 + if in_hole:
  123 +
  124 + point_intersection: Geometry = line.Intersection(in_hole_line)
  125 + plist = []
  126 + for i in range(point_intersection.GetGeometryCount()):
  127 + pi = point_intersection.GetGeometryRef(i)
  128 + plist.append(pi)
  129 + plist_d = [(pi,center.Distance(pi)) for pi in plist]
  130 + plist_d.sort(key=lambda x:x[1])
  131 +
  132 + nearest_point= plist_d[0][0]
  133 + firt_short_length = short_length/20.0
  134 + radline,other_point = self.get_radline(center.GetX(),center.GetY(),nearest_point.GetX(),nearest_point.GetY(),firt_short_length)
  135 + # print("\"" + other_point.ExportToWkt() + "\",")
  136 +
  137 +
  138 + while not polygon.Contains(other_point):
  139 +
  140 + firt_short_length = firt_short_length / 2
  141 + radline, other_point = self.get_radline(center.GetX(), center.GetY(), nearest_point.GetX(),
  142 + nearest_point.GetY(), firt_short_length)
  143 +
  144 +
  145 +
  146 + return RepresentPoint(other_point,polygon)
  147 +
  148 +
  149 + point_intersection:Geometry = line.Intersection(polygon_line)
  150 + xlist = []
  151 + ylist = []
  152 + plist = []
  153 +
  154 + for i in range(point_intersection.GetGeometryCount()):
  155 + pi = point_intersection.GetGeometryRef(i)
  156 + xlist.append(pi.GetX())
  157 + ylist.append(pi.GetY())
  158 + plist.append(pi)
  159 +
  160 + reprecent_point = [(min(xlist)+max(xlist))/2.0,(min(ylist)+max(ylist))/2.0]
  161 +
  162 + reprecent_point = self.creat_point(reprecent_point)
  163 +
  164 + if not polygon.Contains(reprecent_point):
  165 + plist_d = [(pi,center.Distance(pi)) for pi in plist]
  166 + plist_d.sort(key=lambda x:x[1])
  167 + 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))
  168 +
  169 + # print("\""+reprecent_point.ExportToWkt() + "\",")
  170 +
  171 + rp = RepresentPoint(reprecent_point,polygon)
  172 +
  173 + return rp
  174 +
  175 +
  176 +
  177 +
  178 +
  179 + def get_line(self, x0, y0 , angle, r):
  180 +
  181 + line: Geometry = ogr.Geometry(ogr.wkbLineString)
  182 + line.AddPoint(x0, y0)
  183 + hudu = angle/360.0 * 2 * math.pi
  184 + dx = math.sin(hudu) * r
  185 + dy = math.cos(hudu) * r
  186 + line.AddPoint(x0+dx, y0+dy)
  187 +
  188 + return line
  189 +
  190 + def get_doubleline(self, x0, y0 , angle, r):
  191 +
  192 + line: Geometry = ogr.Geometry(ogr.wkbLineString)
  193 +
  194 + hudu = angle/360.0 * 2 * math.pi
  195 + dx = math.sin(hudu) * r
  196 + dy = math.cos(hudu) * r
  197 +
  198 + hudu = (angle+180)/360.0 * 2 * math.pi
  199 + dx2 = math.sin(hudu) * r
  200 + dy2 = math.cos(hudu) * r
  201 +
  202 + line.AddPoint(x0 + dx2, y0 + dy2)
  203 + line.AddPoint(x0+dx, y0+dy)
  204 +
  205 + return line
  206 +
  207 +
  208 + def get_radline(self,x0,y0,x1,y1,len_size):
  209 + a2 = math.pow((x1-x0),2)
  210 + b2 = math.pow((y1-y0),2)
  211 + len_size = len_size+ math.sqrt(a2+b2)
  212 +
  213 + line: Geometry = ogr.Geometry(ogr.wkbLineString)
  214 + line.AddPoint(x0, y0)
  215 + tanx = abs(y1-y0) / abs(x1-x0)
  216 + cosx = 1 / math.sqrt(1 + tanx *tanx)
  217 + dx = cosx* len_size
  218 + dy = tanx * dx
  219 +
  220 + if x1 == x0:
  221 + x2 = x0
  222 + if y1 > y0 :
  223 + y2 = y0 + abs(dy)
  224 + else:
  225 + y2 = y0 - abs(dy)
  226 + else:
  227 + if x1 < x0:
  228 + x2 = x0 - dx
  229 + else:
  230 + x2 = x0 + dx
  231 +
  232 + if y1 < y0:
  233 + y2 = y0 - dy
  234 + else:
  235 + y2 = y0 + dy
  236 +
  237 + line.AddPoint(x2, y2)
  238 +
  239 + other_point = ogr.Geometry(ogr.wkbPoint)
  240 + other_point.AddPoint(x2, y2)
  241 +
  242 + return line , other_point
  243 +
  244 + def get_direction(self,polygon,center,line_length):
  245 + '''
  246 + 判断旋转方向
  247 + :param polygon:
  248 + :param center:
  249 + :param line_length:
  250 + :return:
  251 + '''
  252 +
  253 + line = self.get_line(center.GetX(),center.GetY(),0,line_length)
  254 +
  255 + oneside_area, otherside_area = self.jude(polygon,line,0,line_length)
  256 +
  257 + if oneside_area == 0 and otherside_area == 0 :
  258 + return range(0, 390, 30)
  259 + else:
  260 + line = self.get_line(center.GetX(), center.GetY(), 10, line_length)
  261 + oneside_area_contrast, otherside_area_contrast = self.jude(polygon, line, 30, line_length)
  262 +
  263 + if oneside_area_contrast == 0 and otherside_area_contrast == 0:
  264 + return range(360, -30, -30)
  265 + else:
  266 + if abs(oneside_area - otherside_area) > abs(oneside_area_contrast - otherside_area_contrast):
  267 + return range(0, 390, 30)
  268 + else:
  269 + return range(360, -30, -30)
  270 +
  271 +
  272 + def jude(self,polygon,line,angle,line_length):
  273 +
  274 + line_buffer: Geometry = line.Buffer(line_length / self.buffer_threshold)
  275 + clip_geom: Geometry = polygon.Difference(line_buffer)
  276 +
  277 + oneside_area = 0
  278 + otherside_area = 0
  279 +
  280 + gc = clip_geom.GetGeometryCount()
  281 + if gc <= 1:
  282 + oneside_area = 0
  283 + otherside_area = 0
  284 + else:
  285 + triangle1, triangle2 = self.get_side_triangle(line, angle)
  286 +
  287 +
  288 + for gi in range(clip_geom.GetGeometryCount()):
  289 + clip_geom_i: Geometry = clip_geom.GetGeometryRef(gi)
  290 + it = clip_geom_i.Intersection(triangle1)
  291 +
  292 + if clip_geom_i.Intersect(triangle1) and it.Buffer(line_length / self.buffer_threshold).Intersect(
  293 + line_buffer):
  294 + oneside_area += clip_geom_i.GetArea()
  295 + else:
  296 + otherside_area += clip_geom_i.GetArea()
  297 + return oneside_area, otherside_area
  298 +
  299 + def division(self,polygon,center,in_hole,line_length,angle1,angle2,area_thre):
  300 +
  301 + mid_angle = (angle1 + angle2)/2.0
  302 + if in_hole:
  303 + line = self.get_doubleline(center.GetX(), center.GetY(), mid_angle, line_length)
  304 + else:
  305 + line = self.get_line(center.GetX(), center.GetY(), mid_angle, line_length)
  306 +
  307 + one,other = self.jude(polygon,line,mid_angle,line_length)
  308 +
  309 + while abs(one - other) > area_thre:
  310 + if one > other:
  311 + if angle1 > angle2:
  312 + return self.division(polygon, center, in_hole, line_length, angle2, mid_angle, area_thre)
  313 + else:
  314 + return self.division(polygon, center, in_hole, line_length, mid_angle, angle1, area_thre)
  315 + else:
  316 + if angle1 > angle2:
  317 + return self.division(polygon, center, in_hole, line_length, mid_angle, angle1, area_thre)
  318 + else:
  319 + return self.division(polygon, center, in_hole, line_length, angle2, mid_angle, area_thre)
  320 + return line
  321 +
  322 +
  323 + def get_side_triangle(self,line:Geometry,angle):
  324 + '''
  325 + 获取方向三角形
  326 + :param line:
  327 + :param angle:
  328 + :return:
  329 + '''
  330 +
  331 + start = line.GetPoint(0)
  332 + end = line.GetPoint(1)
  333 +
  334 +
  335 + angle_t = angle-30
  336 + hudu = angle_t/360.0 * 2 * math.pi
  337 +
  338 + r = line.Length() / (2*math.cos( math.pi/6))
  339 + dx = math.sin(hudu) * r
  340 + dy = math.cos(hudu) * r
  341 +
  342 +
  343 + ring1 = ogr.Geometry(ogr.wkbLinearRing)
  344 + ring1.AddPoint(start[0], start[1])
  345 + ring1.AddPoint(start[0] + dx, start[1] + dy)
  346 + ring1.AddPoint(end[0], end[1])
  347 + ring1.AddPoint(start[0], start[1])
  348 + triangle1 = ogr.Geometry(ogr.wkbPolygon)
  349 + triangle1.AddGeometry(ring1)
  350 +
  351 +
  352 + angle_t = angle+30
  353 + hudu = angle_t/360.0 * 2 * math.pi
  354 +
  355 + r = line.Length() / (2*math.cos( math.pi/6))
  356 +
  357 + dx = math.sin(hudu) * r
  358 + dy = math.cos(hudu) * r
  359 +
  360 + ring2 = ogr.Geometry(ogr.wkbLinearRing)
  361 + ring2.AddPoint(start[0], start[1])
  362 + ring2.AddPoint(start[0]+dx, start[1]+dy)
  363 + ring2.AddPoint(end[0], end[1])
  364 + ring2.AddPoint(start[0], start[1])
  365 + triangle2 = ogr.Geometry(ogr.wkbPolygon)
  366 + triangle2.AddGeometry(ring2)
  367 +
  368 + return triangle1,triangle2
  369 +
  370 +
  371 + def creat_point(self,tuple):
  372 + p: Geometry = ogr.Geometry(ogr.wkbPoint)
  373 + p.AddPoint(tuple[0], tuple[1])
  374 + return p
  375 +
  376 +
  377 +
  378 +
  379 + def create_delauney(self,rps):
  380 + multipoint: Geometry = ogr.Geometry(ogr.wkbMultiPoint)
  381 +
  382 + rp_dict = {}
  383 + line_set = set()
  384 + delauney_lines = []
  385 +
  386 + for rp in rps:
  387 + multipoint.AddGeometry(rp.point)
  388 +
  389 + rp_dict[rp.point.GetPoint(0).__str__()] = rp
  390 +
  391 + delauney:Geometry = multipoint.DelaunayTriangulation()
  392 +
  393 + for index in range(delauney.GetGeometryCount()):
  394 + triangle = delauney.GetGeometryRef(index)
  395 +
  396 + triangle_line:Geometry = ogr.ForceToLineString(triangle)
  397 +
  398 +
  399 + for pi in range(triangle_line.GetPointCount()-1):
  400 + p = triangle_line.GetPoint(pi)
  401 + p_next = triangle_line.GetPoint(pi+1)
  402 +
  403 + if p[0] < p_next[0]:
  404 + key = "{}{}".format(p.__str__(),p_next.__str__())
  405 + elif p[0] > p_next[0]:
  406 + key = "{}{}".format(p_next.__str__(), p.__str__())
  407 + else:
  408 + if p[1] < p_next[1]:
  409 + key = "{}{}".format(p.__str__(), p_next.__str__())
  410 + else:
  411 + key = "{}{}".format(p_next.__str__(), p.__str__())
  412 +
  413 + if not line_set.__contains__(key):
  414 + line_set.add(key)
  415 + rp1 = rp_dict.get(p.__str__())
  416 + rp2 = rp_dict.get(p_next.__str__())
  417 +
  418 + delauney_line = DelauneyLine(rp1,rp2)
  419 + delauney_lines.append(delauney_line)
  420 +
  421 + return delauney_lines
  422 +
  423 +
  424 +
  425 + def create_min_delauney(self,delauney_lines,rps,polygons):
  426 + '''
  427 + 使用prim算法计算最小生成树
  428 + :param delauney_lines:
  429 + :param polygons:
  430 + :return:
  431 + '''
  432 +
  433 + kv = {}
  434 + rps_set = set(rps)
  435 +
  436 + for delauney_line in delauney_lines:
  437 + if kv.get(delauney_line.rp1):
  438 +
  439 + kv[delauney_line.rp1].add(delauney_line)
  440 + else:
  441 + kv[delauney_line.rp1] = set()
  442 + kv[delauney_line.rp1].add(delauney_line)
  443 +
  444 + if kv.get(delauney_line.rp2):
  445 +
  446 + kv[delauney_line.rp2].add(delauney_line)
  447 + else:
  448 +
  449 + kv[delauney_line.rp2] = set()
  450 + kv[delauney_line.rp2].add(delauney_line)
  451 +
  452 +
  453 + #初始化树
  454 + delauney_lines = sorted(delauney_lines,key=lambda x:x.distance)
  455 +
  456 +
  457 + delauney_min_tree = DelauneyMinTree()
  458 + delauney_min_tree.append(delauney_lines[0])
  459 +
  460 + rps_set.remove(delauney_lines[0].rp1)
  461 + rps_set.remove(delauney_lines[0].rp2)
  462 + kv[delauney_lines[0].rp1].remove(delauney_lines[0])
  463 + kv[delauney_lines[0].rp2].remove(delauney_lines[0])
  464 +
  465 +
  466 + while rps_set.__len__()>0:
  467 +
  468 + relate_delauney_line = delauney_min_tree.get_other_relate_delauney_lines(kv)
  469 +
  470 + relate_delauney_line_sort = sorted(relate_delauney_line,key=lambda x:x.distance)
  471 +
  472 + min_distance_line = relate_delauney_line_sort[0]
  473 +
  474 + #删除
  475 + other_rp = delauney_min_tree.get_other_rp(min_distance_line)
  476 + if other_rp is None:
  477 + kv[min_distance_line.rp1].remove(min_distance_line)
  478 + kv[min_distance_line.rp2].remove(min_distance_line)
  479 + continue
  480 +
  481 + delauney_min_tree.append(min_distance_line)
  482 +
  483 + rps_set.remove(other_rp)
  484 +
  485 + kv[min_distance_line.rp1].remove(min_distance_line)
  486 + kv[min_distance_line.rp2].remove(min_distance_line)
  487 +
  488 +
  489 +
  490 + for l in delauney_min_tree.delauney_lines_list:
  491 + line = l.line
  492 + # print("\"" + line.ExportToWkt() + "\",")
  493 +
  494 + # print(delauney_min_tree.delauney_lines_list.__len__())
  495 +
  496 + return delauney_min_tree
  497 +
  498 + def cut_delauney_min_tree(self,delauney_min_tree:DelauneyMinTree,threshold):
  499 +
  500 + trees = []
  501 + kv = {}
  502 +
  503 + count = 0
  504 +
  505 + for delauney_line in delauney_min_tree.delauney_lines_list:
  506 +
  507 + dn1 = kv.get(delauney_line.rp1)
  508 + dn2 = kv.get(delauney_line.rp2)
  509 +
  510 +
  511 + if not dn1:
  512 + dn1 = DelauneyNode(delauney_line.rp1)
  513 + kv[delauney_line.rp1] = dn1
  514 +
  515 + if not dn2:
  516 +
  517 + trees.append(dn1)
  518 +
  519 + dn2 = DelauneyNode(delauney_line.rp2)
  520 + kv[delauney_line.rp2] = dn2
  521 +
  522 + if delauney_line.distance < threshold:
  523 + dn1.add_children(dn2,delauney_line)
  524 + count +=1
  525 +
  526 + else:
  527 + #断开
  528 + trees.append(dn2)
  529 + else:
  530 +
  531 + if delauney_line.distance < threshold:
  532 + dn2.add_children(dn1,delauney_line)
  533 + count += 1
  534 + else:
  535 + trees.append(dn1)
  536 + else:
  537 +
  538 + dn2 = DelauneyNode(delauney_line.rp2)
  539 + kv[delauney_line.rp2] = dn2
  540 +
  541 + if delauney_line.distance < threshold:
  542 + dn1.add_children(dn2,delauney_line)
  543 + count += 1
  544 + else:
  545 + trees.append(dn2)
  546 +
  547 +
  548 + return trees
  549 +
  550 + def merge(self,trees):
  551 +
  552 + polygons = []
  553 + for tree in trees:
  554 +
  555 + merge_polygon_raw = list()
  556 +
  557 + dls = tree.get_delauney_lines()
  558 + for dl in dls:
  559 + p1 = dl.rp1.polygon
  560 + p2 = dl.rp2.polygon
  561 +
  562 + merge_polygon_raw.append(p1)
  563 + merge_polygon_raw.append(p2)
  564 + line = dl.line
  565 +
  566 + p1_lines = self.get_polygon_lines(p1)
  567 + p2_lines = self.get_polygon_lines(p2)
  568 +
  569 + p1_intersect_lines = [l for l in p1_lines if l.Intersect(line)]
  570 + p2_intersect_lines = [l for l in p2_lines if l.Intersect(line)]
  571 +
  572 + if p1_intersect_lines.__len__()>1:
  573 + p1_intersect_lines = sorted(p1_intersect_lines,key=lambda x:p2.Distance(x))
  574 + p1_intersect_line_rep = p1_intersect_lines[0]
  575 + elif p1_intersect_lines.__len__()==1:
  576 + p1_intersect_line_rep = p1_intersect_lines[0]
  577 + else:
  578 + continue
  579 +
  580 +
  581 + if p2_intersect_lines.__len__()>1:
  582 + p2_intersect_lines = sorted(p2_intersect_lines,key=lambda x:p1.Distance(x))
  583 + p2_intersect_line_rep = p2_intersect_lines[0]
  584 + elif p2_intersect_lines.__len__()==1:
  585 + p2_intersect_line_rep = p2_intersect_lines[0]
  586 + else:
  587 + continue
  588 +
  589 +
  590 + # #两条线没有距离跳过
  591 + # if p2_intersect_line_rep.Distance(p1_intersect_line_rep) == 0:
  592 + # continue
  593 + # else:
  594 +
  595 + mid_polygon = self.create_mid_polygon(p1_intersect_line_rep,p2_intersect_line_rep,p1,p2)
  596 +
  597 + if mid_polygon.GetArea() > 0.0002116361000058077*0.0002116361000058077:
  598 + continue
  599 +
  600 + merge_polygon_raw.append(mid_polygon)
  601 +
  602 + merge_polygon = None
  603 + for p in merge_polygon_raw:
  604 + if merge_polygon is None:
  605 + merge_polygon = p
  606 + else:
  607 + merge_polygon = merge_polygon.Union(p)
  608 +
  609 + polygons.append(merge_polygon)
  610 +
  611 +
  612 + return polygons
  613 +
  614 +
  615 + def merge2(self,trees):
  616 +
  617 + polygons = []
  618 +
  619 +
  620 +
  621 +
  622 + for tree in trees:
  623 +
  624 + tree_polygons = tree.get_polygons()
  625 +
  626 + points = []
  627 + for p in tree_polygons:
  628 +
  629 + if p.GetGeometryCount() == 1:
  630 + polygon_line: Geometry = ogr.ForceToLineString(p)
  631 +
  632 + polygon_line.Con
  633 + # 有孔Polygon
  634 + else:
  635 + polygon_line: Geometry = ogr.ForceToLineString(p.GetGeometryRef(0))
  636 +
  637 + points.extend(polygon_line.GetPoints()[:-1])
  638 +
  639 + multipoint: Geometry = ogr.Geometry(ogr.wkbMultiPoint)
  640 +
  641 + for p in points:
  642 + poi = ogr.Geometry(ogr.wkbPoint)
  643 + poi.AddPoint(p[0],p[1])
  644 + multipoint.AddGeometry(poi)
  645 +
  646 + delauney: Geometry = multipoint.DelaunayTriangulation()
  647 + merge_polygon = None
  648 +
  649 + for p in delauney:
  650 + # if multi_polygon.Contains(p):
  651 + # continue
  652 +
  653 + pline:Geometry = ogr.ForceToLineString(p)
  654 + pline :list = pline.GetPoints()
  655 + pline.append(pline[1])
  656 +
  657 +
  658 + pass_or_not = False
  659 + for indx in range(3):
  660 + p1 = pline[indx]
  661 + p2 = pline[indx+1]
  662 +
  663 + ppline:Geometry = ogr.Geometry(ogr.wkbLineString)
  664 + ppline.AddPoint(p1[0],p1[1])
  665 + ppline.AddPoint(p2[0], p2[1])
  666 +
  667 +
  668 +
  669 + p3:Geometry = ogr.Geometry(ogr.wkbPoint)
  670 + p3.AddPoint(pline[indx+2][0], pline[indx+2][1])
  671 +
  672 + if p3.Distance(ppline) > 0.0002116361000058077 or ppline.Length() > 0.0002116361000058077:
  673 + pass_or_not = True
  674 + break
  675 +
  676 + if pass_or_not:
  677 + continue
  678 +
  679 + if merge_polygon is None:
  680 + merge_polygon = p
  681 + else:
  682 + merge_polygon = merge_polygon.Union(p)
  683 +
  684 +
  685 +
  686 + polygons.append(merge_polygon)
  687 +
  688 +
  689 + return polygons
  690 +
  691 + def merge_circle(self):
  692 + pass
  693 +
  694 +
  695 + def create_mid_polygon(self,p1_intersect_line_rep,p2_intersect_line_rep,p1,p2):
  696 + '''
  697 + 创建衔接polygon
  698 + :param line:
  699 + :return:
  700 + '''
  701 +
  702 + if p1_intersect_line_rep.Intersect(p2_intersect_line_rep):
  703 +
  704 + p1_rep_p1 = p1_intersect_line_rep.GetPoints()[0]
  705 + p1_rep_p2 = p1_intersect_line_rep.GetPoints()[1]
  706 +
  707 + p2_rep_p1 = p2_intersect_line_rep.GetPoints()[0]
  708 + p2_rep_p2 = p2_intersect_line_rep.GetPoints()[1]
  709 +
  710 + polygon = self.create_polygon(p1_rep_p1, p2_rep_p2, p1_rep_p2, p2_rep_p1)
  711 +
  712 + else:
  713 +
  714 + p1_rep_p1 = p1_intersect_line_rep.GetPoints()[0]
  715 + p1_rep_p2 = p1_intersect_line_rep.GetPoints()[1]
  716 +
  717 + p2_rep_p1 = p2_intersect_line_rep.GetPoints()[0]
  718 + p2_rep_p2 = p2_intersect_line_rep.GetPoints()[1]
  719 +
  720 + line1 = ogr.Geometry(ogr.wkbLineString)
  721 +
  722 +
  723 + line1.AddPoint(p1_rep_p1[0], p1_rep_p1[1])
  724 + line1.AddPoint(p2_rep_p1[0], p2_rep_p1[1])
  725 +
  726 + line2 = ogr.Geometry(ogr.wkbLineString)
  727 + line2.AddPoint(p1_rep_p2[0], p1_rep_p2[1])
  728 + line2.AddPoint(p2_rep_p2[0], p2_rep_p2[1])
  729 +
  730 + if line1.Intersect(line2):
  731 + polygon = self.create_polygon(p1_rep_p1, p1_rep_p2, p2_rep_p1, p2_rep_p2)
  732 + else:
  733 +
  734 + polygon = self.create_polygon(p1_rep_p1, p1_rep_p2, p2_rep_p2, p2_rep_p1)
  735 + if polygon.Intersect(p1) or polygon.Intersect(p2):
  736 + polygon = self.create_polygon(p1_rep_p1, p1_rep_p2, p2_rep_p1, p2_rep_p2)
  737 +
  738 +
  739 + return polygon
  740 +
  741 + def create_polygon(self,p1,p2,p3,p4):
  742 +
  743 + ring = ogr.Geometry(ogr.wkbLinearRing)
  744 + ring.AddPoint(p1[0], p1[1])
  745 + ring.AddPoint(p2[0], p2[1])
  746 + ring.AddPoint(p3[0], p3[1])
  747 + ring.AddPoint(p4[0], p4[1])
  748 + ring.AddPoint(p1[0], p1[1])
  749 +
  750 + poly = ogr.Geometry(ogr.wkbPolygon)
  751 + poly.AddGeometry(ring)
  752 + return poly
  753 +
  754 +
  755 + def get_polygon_lines(self,polygon):
  756 + #无孔Polygon
  757 + if polygon.GetGeometryCount() == 1:
  758 + polygon_line : Geometry = ogr.ForceToLineString(polygon)
  759 + # 有孔Polygon
  760 + else:
  761 + polygon_line : Geometry = ogr.ForceToLineString(polygon.GetGeometryRef(0))
  762 +
  763 + points = polygon_line.GetPoints()
  764 +
  765 + lines = []
  766 + for index in range(len(points)-1):
  767 +
  768 + point_start = points[index]
  769 + point_end = points[index+1]
  770 + line = ogr.Geometry(ogr.wkbLineString)
  771 + line.AddPoint(point_start[0], point_start[1])
  772 + line.AddPoint(point_end[0], point_end[1])
  773 +
  774 + lines.append(line)
  775 +
  776 + return lines
  777 +
  778 + def merge_concave(self, trees, distance_threshold):
  779 + merge_polygons = []
  780 + for tree in trees:
  781 + polygons = list(tree.get_polygons())
  782 +
  783 + merge_raw: Geometry = polygons[0]
  784 + for p in polygons:
  785 + merge_raw = merge_raw.Union(p)
  786 +
  787 + points = []
  788 + dd= merge_raw.GetGeometryCount()
  789 +
  790 + for i in range(merge_raw.GetGeometryCount()):
  791 +
  792 + poly = merge_raw.GetGeometryRef(i)
  793 + if poly.GetGeometryCount() == 1:
  794 + poly_line: Geometry = ogr.ForceToLineString(poly)
  795 + # 有孔Polygon
  796 + else:
  797 + poly_line: Geometry = ogr.ForceToLineString(poly.GetGeometryRef(0))
  798 + if poly_line:
  799 + for indx in range(poly_line.GetPointCount() - 1):
  800 + poi = poly_line.GetPoint(indx)
  801 +
  802 + points.append(poi)
  803 +
  804 + poi_next = poly_line.GetPoint(indx + 1)
  805 +
  806 + dis = math.sqrt(math.pow(poi[0] - poi_next[0], 2) + math.pow(poi[1] - poi_next[1], 2))
  807 + # print(dis)
  808 + if dis > distance_threshold:
  809 + times = int(dis / distance_threshold)
  810 + # print(times)
  811 + for time in range(1, times + 1):
  812 + x, y = self.get_subpoint(poi[0], poi[1], poi_next[0], poi_next[1], (time * distance_threshold))
  813 + points.append([x, y])
  814 +
  815 + points = np.array([[p[0], p[1]] for p in points])
  816 +
  817 + for pp in points:
  818 + poi = ogr.Geometry(ogr.wkbPoint)
  819 + poi.AddPoint(pp[0], pp[1])
  820 +
  821 + merge_p_line = concaveHull(points, 3)
  822 +
  823 + ring = ogr.Geometry(ogr.wkbLinearRing)
  824 +
  825 + merge_p = ogr.Geometry(ogr.wkbPolygon)
  826 +
  827 + for l in merge_p_line:
  828 + ring.AddPoint(l[0], l[1])
  829 +
  830 + ring.AddPoint(merge_p_line[0][0], merge_p_line[0][1])
  831 +
  832 + merge_p.AddGeometry(ring)
  833 +
  834 + merge_polygons.append(merge_p)
  835 +
  836 + return merge_polygons
  837 +
  838 + def get_subpoint(self, x0, y0, x1, y1, len_size):
  839 +
  840 + len_size = len_size
  841 + tanx = abs(y1 - y0) / abs(x1 - x0)
  842 + cosx = 1 / math.sqrt(1 + tanx * tanx)
  843 + dx = cosx * len_size
  844 + dy = tanx * dx
  845 +
  846 + if x1 == x0:
  847 + x2 = x0
  848 + if y1 > y0:
  849 + y2 = y0 + abs(dy)
  850 + else:
  851 + y2 = y0 - abs(dy)
  852 + else:
  853 + if x1 < x0:
  854 + x2 = x0 - dx
  855 + else:
  856 + x2 = x0 + dx
  857 +
  858 + if y1 < y0:
  859 + y2 = y0 - dy
  860 + else:
  861 + y2 = y0 + dy
  862 +
  863 + return x2, y2
  864 +
  865 + def process(self):
  866 + polygons = self.data.get_polygons()
  867 + rps = []
  868 + for poly in polygons:
  869 + rp = self.get_polygon_reprecent_point(poly)
  870 + rps.append(rp)
  871 +
  872 + delauney_lines = self.create_delauney(rps)
  873 +
  874 + min_delauney = self.create_min_delauney(delauney_lines,rps,polygons)
  875 +
  876 + trees = self.cut_delauney_min_tree(min_delauney,self.distance_buffer_threshold)
  877 +
  878 + print(len(trees))
  879 + polygons = self.merge_concave(trees,0.00007)
  880 +
  881 + return [p.ExportToWkt() for p in polygons]
  882 +
  883 +if __name__ == '__main__':
  884 +
  885 +
  886 + # print(sd.get_polygons()[0])
  887 + # sd.close()
  888 +
  889 +
  890 + sd = ShapeData(r"J:\Data\制图综合\example.shp")
  891 +
  892 + ext = sd.layer.GetExtent()
  893 + threshold = (ext[1]-ext[0])/20
  894 + print(threshold)
  895 +
  896 +
  897 + zh = Zonghe(sd)
  898 + wkts = zh.process()
  899 +
  900 + result = r"J:\Data\制图综合\zhonghe_concave2.shp"
  901 + ShapeData.create_shp_fromwkts(result,"zh",wkts)
  902 +
注册登录 后发表评论