正在显示
26 个修改的文件
包含
737 行增加
和
252 行删除
@@ -17,7 +17,7 @@ from app.util.component.StructurePrint import StructurePrint | @@ -17,7 +17,7 @@ from app.util.component.StructurePrint import StructurePrint | ||
17 | from app.util.component.PGUtil import PGUtil | 17 | from app.util.component.PGUtil import PGUtil |
18 | import os | 18 | import os |
19 | from app.modules.monitor.schedule import start_schedule | 19 | from app.modules.monitor.schedule import start_schedule |
20 | -import requests | 20 | +import platform |
21 | 21 | ||
22 | class JSONEncoder(_JSONEncoder): | 22 | class JSONEncoder(_JSONEncoder): |
23 | """ | 23 | """ |
@@ -128,7 +128,7 @@ def create_app(): | @@ -128,7 +128,7 @@ def create_app(): | ||
128 | 128 | ||
129 | # 不检测https | 129 | # 不检测https |
130 | os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' | 130 | os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' |
131 | - | ||
132 | - start_schedule() | 131 | + if platform.system().lower() == "linux": |
132 | + start_schedule() | ||
133 | return app | 133 | return app |
134 | 134 |
@@ -13,7 +13,7 @@ import time | @@ -13,7 +13,7 @@ import time | ||
13 | from app.models import SM3, AESHelper | 13 | from app.models import SM3, AESHelper |
14 | from app.util.component.StructurePrint import StructurePrint | 14 | from app.util.component.StructurePrint import StructurePrint |
15 | import traceback | 15 | import traceback |
16 | -from oauthlib import oauth2 | 16 | +# from oauthlib import oauth2 |
17 | import requests | 17 | import requests |
18 | from app.modules.auth.models import OAuth2Token, User, db | 18 | from app.modules.auth.models import OAuth2Token, User, db |
19 | 19 |
@@ -37,7 +37,7 @@ class Api(ApiTemplate): | @@ -37,7 +37,7 @@ class Api(ApiTemplate): | ||
37 | download_process.start() | 37 | download_process.start() |
38 | 38 | ||
39 | task = Task(guid=task_guid, | 39 | task = Task(guid=task_guid, |
40 | - name="下载|{}".format(self.para.get("table_name")), | 40 | + name="下载 | {}".format(self.para.get("table_name")), |
41 | create_time=datetime.datetime.now(), | 41 | create_time=datetime.datetime.now(), |
42 | state=0, | 42 | state=0, |
43 | task_type=4, | 43 | task_type=4, |
@@ -83,7 +83,7 @@ class Api(ApiTemplate): | @@ -83,7 +83,7 @@ class Api(ApiTemplate): | ||
83 | # 录入数据后台进程,录入主函数为entry | 83 | # 录入数据后台进程,录入主函数为entry |
84 | # 初始化task | 84 | # 初始化task |
85 | task = Task(guid=self.para.get("task_guid"), | 85 | task = Task(guid=self.para.get("task_guid"), |
86 | - name="入库|{}".format(self.para.get("task_name")), | 86 | + name="入库 | {}".format(self.para.get("task_name")), |
87 | create_time=datetime.datetime.now(), | 87 | create_time=datetime.datetime.now(), |
88 | state=0, | 88 | state=0, |
89 | task_type=1, | 89 | task_type=1, |
@@ -323,6 +323,7 @@ class ThisTask: | @@ -323,6 +323,7 @@ class ThisTask: | ||
323 | this_time = datetime.datetime.now() | 323 | this_time = datetime.datetime.now() |
324 | 324 | ||
325 | ext = layer.GetExtent() | 325 | ext = layer.GetExtent() |
326 | + | ||
326 | if ext[0] < 360: | 327 | if ext[0] < 360: |
327 | ext = [round(e, 6) for e in ext] | 328 | ext = [round(e, 6) for e in ext] |
328 | else: | 329 | else: |
@@ -23,7 +23,7 @@ class Api(ApiTemplate): | @@ -23,7 +23,7 @@ class Api(ApiTemplate): | ||
23 | raise Exception("数据不存在!") | 23 | raise Exception("数据不存在!") |
24 | 24 | ||
25 | #验证权限 | 25 | #验证权限 |
26 | - UserCheck.verify(column.relate_table.relate_database.creator) | 26 | + UserCheck.verify(column.relate_table.creator) |
27 | 27 | ||
28 | try: | 28 | try: |
29 | if self.para.get("column_alias"): | 29 | if self.para.get("column_alias"): |
@@ -35,7 +35,7 @@ class Api(ApiTemplate): | @@ -35,7 +35,7 @@ class Api(ApiTemplate): | ||
35 | database = Database.query.filter_by(guid=table.database_guid).one_or_none() | 35 | database = Database.query.filter_by(guid=table.database_guid).one_or_none() |
36 | 36 | ||
37 | #验证权限 | 37 | #验证权限 |
38 | - UserCheck.verify(database.creator) | 38 | + UserCheck.verify(table.creator) |
39 | 39 | ||
40 | if not database: | 40 | if not database: |
41 | res["result"]=False | 41 | res["result"]=False |
@@ -33,7 +33,7 @@ class Api(ApiTemplate): | @@ -33,7 +33,7 @@ class Api(ApiTemplate): | ||
33 | return res | 33 | return res |
34 | 34 | ||
35 | #验证权限 | 35 | #验证权限 |
36 | - UserCheck.verify(table.one_or_none().relate_database.creator) | 36 | + UserCheck.verify(table.one_or_none().creator) |
37 | 37 | ||
38 | if self.para.__contains__("catalog_guid"): | 38 | if self.para.__contains__("catalog_guid"): |
39 | if catalog_guid is None: | 39 | if catalog_guid is None: |
@@ -39,7 +39,7 @@ class Api(ApiTemplate): | @@ -39,7 +39,7 @@ class Api(ApiTemplate): | ||
39 | refresh_process.start() | 39 | refresh_process.start() |
40 | 40 | ||
41 | task = Task(guid=task_guid, | 41 | task = Task(guid=task_guid, |
42 | - name="更新|{}".format(database.alias), | 42 | + name="更新 | {}".format(database.alias), |
43 | create_time=datetime.datetime.now(), | 43 | create_time=datetime.datetime.now(), |
44 | state=0, | 44 | state=0, |
45 | task_type=3, | 45 | task_type=3, |
@@ -335,7 +335,7 @@ class Api(ApiTemplate): | @@ -335,7 +335,7 @@ class Api(ApiTemplate): | ||
335 | try: | 335 | try: |
336 | # 删除表 | 336 | # 删除表 |
337 | if table.name not in db_tables_names: | 337 | if table.name not in db_tables_names: |
338 | - StructurePrint().print("空间表减少!") | 338 | + StructurePrint().print("{}空间表减少!".format(table.name)) |
339 | sys_session.delete(table) | 339 | sys_session.delete(table) |
340 | # 修改表 | 340 | # 修改表 |
341 | else: | 341 | else: |
@@ -42,7 +42,7 @@ class Api(ApiTemplate): | @@ -42,7 +42,7 @@ class Api(ApiTemplate): | ||
42 | raise Exception("数据不存在!") | 42 | raise Exception("数据不存在!") |
43 | 43 | ||
44 | #验证权限 | 44 | #验证权限 |
45 | - UserCheck.verify(table.relate_database.creator) | 45 | + UserCheck.verify(table.creator) |
46 | 46 | ||
47 | pg_ds :DataSource= PGUtil.open_pg_data_source(0,DES.decode(table.relate_database.sqlalchemy_uri)) | 47 | pg_ds :DataSource= PGUtil.open_pg_data_source(0,DES.decode(table.relate_database.sqlalchemy_uri)) |
48 | layer = pg_ds.GetLayerByName(table.name) | 48 | layer = pg_ds.GetLayerByName(table.name) |
@@ -76,7 +76,7 @@ class Api(ApiTemplate): | @@ -76,7 +76,7 @@ class Api(ApiTemplate): | ||
76 | 76 | ||
77 | 77 | ||
78 | task = Task(guid=task_guid, | 78 | task = Task(guid=task_guid, |
79 | - name="矢量金字塔|{}".format(table.name), | 79 | + name="矢量金字塔 | {}".format(table.name), |
80 | table_guid=table_guid, | 80 | table_guid=table_guid, |
81 | create_time=datetime.datetime.now(), | 81 | create_time=datetime.datetime.now(), |
82 | state=0, | 82 | state=0, |
@@ -42,7 +42,7 @@ class Api(ApiTemplate): | @@ -42,7 +42,7 @@ class Api(ApiTemplate): | ||
42 | raise Exception("数据不存在!") | 42 | raise Exception("数据不存在!") |
43 | 43 | ||
44 | #验证权限 | 44 | #验证权限 |
45 | - UserCheck.verify(table.relate_database.creator) | 45 | + UserCheck.verify(table.creator) |
46 | 46 | ||
47 | # 判断图层是否存在 | 47 | # 判断图层是否存在 |
48 | 48 | ||
@@ -80,7 +80,7 @@ class Api(ApiTemplate): | @@ -80,7 +80,7 @@ class Api(ApiTemplate): | ||
80 | 80 | ||
81 | task = Task(guid=task_guid, | 81 | task = Task(guid=task_guid, |
82 | # name="矢量金字塔|{},网格大小:{}".format(table.name,self.para.get("grids")), | 82 | # name="矢量金字塔|{},网格大小:{}".format(table.name,self.para.get("grids")), |
83 | - name="矢量金字塔|{}".format(table.name), | 83 | + name="矢量金字塔 | {}".format(table.name), |
84 | table_guid=table_guid, | 84 | table_guid=table_guid, |
85 | create_time=datetime.datetime.now(), | 85 | create_time=datetime.datetime.now(), |
86 | state=0, | 86 | state=0, |
@@ -33,7 +33,7 @@ class Api(ApiTemplate): | @@ -33,7 +33,7 @@ class Api(ApiTemplate): | ||
33 | 33 | ||
34 | 34 | ||
35 | task = Task(guid=task_guid, | 35 | task = Task(guid=task_guid, |
36 | - name="影像金字塔|{}".format(self.para.get("alias")), | 36 | + name="影像金字塔 | {}".format(self.para.get("alias")), |
37 | create_time=datetime.datetime.now(), | 37 | create_time=datetime.datetime.now(), |
38 | state=0, | 38 | state=0, |
39 | task_type=5, | 39 | task_type=5, |
@@ -3,13 +3,12 @@ | @@ -3,13 +3,12 @@ | ||
3 | #createtime: 2021/7/19 | 3 | #createtime: 2021/7/19 |
4 | #email: nheweijun@sina.com | 4 | #email: nheweijun@sina.com |
5 | 5 | ||
6 | - | ||
7 | from app.util.component.ApiTemplate import ApiTemplate | 6 | from app.util.component.ApiTemplate import ApiTemplate |
8 | -from .models import TileService,db,Service,MapService | ||
9 | from app.util.component.ModelVisitor import ModelVisitor | 7 | from app.util.component.ModelVisitor import ModelVisitor |
10 | -from .tile_service.util.ProjectFile import ProjectFile | ||
11 | - | 8 | +from .models import TileService,Service,MapService |
12 | from .util.ServiceType import ServiceType | 9 | from .util.ServiceType import ServiceType |
10 | +from .util.TileProjectFile import ProjectFile | ||
11 | + | ||
13 | class Api(ApiTemplate): | 12 | class Api(ApiTemplate): |
14 | 13 | ||
15 | api_name = "服务reload" | 14 | api_name = "服务reload" |
@@ -5,9 +5,7 @@ | @@ -5,9 +5,7 @@ | ||
5 | 5 | ||
6 | 6 | ||
7 | from app.util.component.ApiTemplate import ApiTemplate | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | -from app.util.component.ModelVisitor import ModelVisitor | ||
9 | from app.util.component.FileProcess import FileProcess | 8 | from app.util.component.FileProcess import FileProcess |
10 | -from .models import Service | ||
11 | import os | 9 | import os |
12 | 10 | ||
13 | class Api(ApiTemplate): | 11 | class Api(ApiTemplate): |
@@ -3,12 +3,12 @@ | @@ -3,12 +3,12 @@ | ||
3 | #createtime: 2021/9/14 | 3 | #createtime: 2021/9/14 |
4 | #email: nheweijun@sina.com | 4 | #email: nheweijun@sina.com |
5 | 5 | ||
6 | +import requests | ||
7 | +import configure | ||
6 | from app.util.component.UserCheck import UserCheck | 8 | from app.util.component.UserCheck import UserCheck |
7 | from app.util.component.ApiTemplate import ApiTemplate | 9 | from app.util.component.ApiTemplate import ApiTemplate |
8 | from .models import Service,db | 10 | from .models import Service,db |
9 | -import requests | ||
10 | from .util.ServiceType import ServiceType | 11 | from .util.ServiceType import ServiceType |
11 | -import configure | ||
12 | 12 | ||
13 | class Api(ApiTemplate): | 13 | class Api(ApiTemplate): |
14 | api_name = "修改服务状态" | 14 | api_name = "修改服务状态" |
@@ -26,20 +26,20 @@ class Api(ApiTemplate): | @@ -26,20 +26,20 @@ class Api(ApiTemplate): | ||
26 | 26 | ||
27 | if service: | 27 | if service: |
28 | service.state = state | 28 | service.state = state |
29 | - db.session.commit() | ||
30 | 29 | ||
31 | - # operate = "startService" if state == 1 else "stopService" | ||
32 | - # server_type = "tileserver" if s_type == "电子地图" else "mapserver" | ||
33 | - # dmap_engine_url = "{}/dmap/api/manager/{}?servicename={}&servername={}".format(configure.dmap_engine, | ||
34 | - # operate,service.name, | ||
35 | - # server_type) | ||
36 | - # state_result = requests.get(dmap_engine_url) | ||
37 | - # if state_result.status_code == 200: | ||
38 | - # if not state_result.json().get("result"): | ||
39 | - # raise Exception("修改服务状态失败!") | ||
40 | - # else: | ||
41 | - # raise Exception("修改服务状态失败!") | ||
42 | 30 | ||
31 | + operate = "startService" if state == 1 else "stopService" | ||
32 | + server_type = "tileserver" if s_type == "电子地图" else "mapserver" | ||
33 | + dmap_engine_url = "{}/dmap/api/manager/{}?servicename={}&servername={}".format(configure.dmap_engine, | ||
34 | + operate,service.name, | ||
35 | + server_type) | ||
36 | + state_result = requests.get(dmap_engine_url) | ||
37 | + if state_result.status_code == 200: | ||
38 | + if state_result.json().get("status") == "false": | ||
39 | + raise Exception("修改服务状态失败!") | ||
40 | + else: | ||
41 | + raise Exception("修改服务状态失败!") | ||
42 | + db.session.commit() | ||
43 | res["result"] = True | 43 | res["result"] = True |
44 | else: | 44 | else: |
45 | raise Exception("服务不存在!") | 45 | raise Exception("服务不存在!") |
@@ -10,7 +10,7 @@ import uuid | @@ -10,7 +10,7 @@ import uuid | ||
10 | from ..models import TileService,Service,db,ServiceFunction,TileScheme | 10 | from ..models import TileService,Service,db,ServiceFunction,TileScheme |
11 | import datetime | 11 | import datetime |
12 | import requests | 12 | import requests |
13 | -from .util.ProjectFile import ProjectFile | 13 | +from ..util.TileProjectFile import ProjectFile |
14 | import json | 14 | import json |
15 | from requests import Response | 15 | from requests import Response |
16 | import configure | 16 | import configure |
@@ -14,7 +14,7 @@ import configure | @@ -14,7 +14,7 @@ import configure | ||
14 | import requests | 14 | import requests |
15 | from requests import Response | 15 | from requests import Response |
16 | import json | 16 | import json |
17 | -from .util.ProjectFile import ProjectFile | 17 | +from ..util.TileProjectFile import ProjectFile |
18 | 18 | ||
19 | class Api(ApiTemplate): | 19 | class Api(ApiTemplate): |
20 | 20 |
@@ -9,7 +9,7 @@ from ..models import TileService,db,Service,MapService | @@ -9,7 +9,7 @@ from ..models import TileService,db,Service,MapService | ||
9 | import configure | 9 | import configure |
10 | from app.util.component.ModelVisitor import ModelVisitor | 10 | from app.util.component.ModelVisitor import ModelVisitor |
11 | 11 | ||
12 | -from .util.ProjectFile import ProjectFile | 12 | +from ..util.TileProjectFile import ProjectFile |
13 | from ..util.ServiceType import ServiceType | 13 | from ..util.ServiceType import ServiceType |
14 | 14 | ||
15 | class Api(ApiTemplate): | 15 | class Api(ApiTemplate): |
@@ -6,10 +6,6 @@ | @@ -6,10 +6,6 @@ | ||
6 | 6 | ||
7 | from app.util.component.ApiTemplate import ApiTemplate | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | import os | 8 | import os |
9 | -from app.util.component.FileProcess import FileProcess | ||
10 | -from app.util.component.SliceScheme import SliceScheme | ||
11 | -import shutil | ||
12 | -from app.util.component.StructurePrint import StructurePrint | ||
13 | from flask import request | 9 | from flask import request |
14 | import uuid | 10 | import uuid |
15 | import configure | 11 | import configure |
@@ -92,21 +92,28 @@ class GeometryAdapter: | @@ -92,21 +92,28 @@ class GeometryAdapter: | ||
92 | # PolyhedralSurface = 15, | 92 | # PolyhedralSurface = 15, |
93 | # LinearRing = 101, | 93 | # LinearRing = 101, |
94 | 94 | ||
95 | + # PointZ = -2147483647 | ||
96 | + # LINESTRINGZ=-2147483646 | ||
97 | + # POLYGONZ=-2147483645 | ||
98 | + | ||
99 | + # PointZM = 3001 | ||
100 | + # LINESTRINGZM= 3002 | ||
101 | + # POLYGONZM= 3003 | ||
102 | + | ||
95 | # MultiPointZ = -2147483644 | 103 | # MultiPointZ = -2147483644 |
96 | # MultiLineStringZ = -2147483643 | 104 | # MultiLineStringZ = -2147483643 |
97 | # MultiPolygonZ = -2147483642 | 105 | # MultiPolygonZ = -2147483642 |
98 | 106 | ||
99 | - # PointZ = -2147483647 | ||
100 | - # LINESTRINGZ=-2147483646 | ||
101 | - # POLYGONZ=-2147483645 | 107 | + # MultiPointZM = 3004 |
108 | + # MultiLineStringZM = 3005 | ||
109 | + # MultiPolygonZM = 3006 | ||
110 | + | ||
102 | 111 | ||
103 | - if raw == 4 or raw == 5 or raw == 6: | ||
104 | - return raw - 3 | ||
105 | - elif raw == -2147483644 or raw == -2147483647: | 112 | + if raw in [1, 4, -2147483644, -2147483647, 3001, 3004] : |
106 | return 1 | 113 | return 1 |
107 | - elif raw == -2147483643 or raw == -2147483646: | 114 | + elif raw in [2, 5, -2147483643, -2147483646, 3002, 3005]: |
108 | return 2 | 115 | return 2 |
109 | - elif raw == -2147483642 or raw == -2147483645: | 116 | + elif raw in [3, 6, -2147483642, -2147483645, 3003, 3006] : |
110 | return 3 | 117 | return 3 |
111 | return raw | 118 | return raw |
112 | 119 |
@@ -34,7 +34,7 @@ class SQLUtil: | @@ -34,7 +34,7 @@ class SQLUtil: | ||
34 | :return: | 34 | :return: |
35 | ''' | 35 | ''' |
36 | pri = session.execute("select * from information_schema.table_privileges " | 36 | pri = session.execute("select * from information_schema.table_privileges " |
37 | - "where grantee='{}' and table_name='{}' and privilege_type='{}' " | 37 | + "where grantee='{}' and table_name='{}' and privilege_type='{}' and table_schema='public' " |
38 | .format(user,table_name,pri_type)).fetchall() | 38 | .format(user,table_name,pri_type)).fetchall() |
39 | if len(pri) == 1: | 39 | if len(pri) == 1: |
40 | return True | 40 | return True |
@@ -9,10 +9,14 @@ import shutil | @@ -9,10 +9,14 @@ import shutil | ||
9 | 9 | ||
10 | def compile(des): | 10 | def compile(des): |
11 | 11 | ||
12 | + | ||
13 | + project_dir = os.path.dirname(os.path.realpath(__file__)) | ||
14 | + if os.path.normpath(project_dir) == os.path.normpath(des): | ||
15 | + raise Exception("目标目录不能与代码目录一样!") | ||
16 | + | ||
12 | if os.path.exists(des): | 17 | if os.path.exists(des): |
13 | os.system("rd/s/q {}".format(des)) | 18 | os.system("rd/s/q {}".format(des)) |
14 | shutil.rmtree(des, True) | 19 | shutil.rmtree(des, True) |
15 | - project_dir = os.path.dirname(os.path.realpath(__file__)) | ||
16 | 20 | ||
17 | shutil.copytree(project_dir, des) | 21 | shutil.copytree(project_dir, des) |
18 | git_path = os.path.join(des,".git") | 22 | git_path = os.path.join(des,".git") |
@@ -353,6 +353,19 @@ AddDefaultCharset UTF-8 | @@ -353,6 +353,19 @@ AddDefaultCharset UTF-8 | ||
353 | #EnableMMAP off | 353 | #EnableMMAP off |
354 | EnableSendfile on | 354 | EnableSendfile on |
355 | 355 | ||
356 | +#3.1.2 | ||
357 | +LoadModule headers_module modules/mod_headers.so | ||
358 | +Header set X-Content-Type-Options nosniff | ||
359 | + | ||
360 | +#3.1.3 | ||
361 | +ServerSignature Off | ||
362 | + | ||
363 | +#3.1.10禁用trace | ||
364 | + off | ||
365 | + | ||
366 | +#3.1.11 | ||
367 | +ServerTokens Prod | ||
368 | + | ||
356 | # Supplemental configuration | 369 | # Supplemental configuration |
357 | # | 370 | # |
358 | # Load config files in the "/etc/httpd/conf.d" directory, if any. | 371 | # Load config files in the "/etc/httpd/conf.d" directory, if any. |
@@ -22,88 +22,20 @@ from osgeo.ogr import * | @@ -22,88 +22,20 @@ from osgeo.ogr import * | ||
22 | import base64 | 22 | import base64 |
23 | 23 | ||
24 | from kazoo.client import KazooClient | 24 | from kazoo.client import KazooClient |
25 | -def query_thread(): | ||
26 | - def get_db_session(db_url, autocommit=False) -> Session: | ||
27 | - engine = create_engine(db_url, pool_size=100) | ||
28 | 25 | ||
29 | - system_session: Session = sessionmaker(bind=engine, autocommit=autocommit)() | ||
30 | - | ||
31 | - return system_session | ||
32 | - | ||
33 | - ses: Session = get_db_session("postgresql://postgres:chinadci@172.26.99.168:5432/postgres") | ||
34 | - bbox = "113.2470703125 22.840576171875,113.258056640625 {}" | ||
35 | - yy= 22.8515625 | ||
36 | - | ||
37 | - table="fs1kw" | ||
38 | - | ||
39 | - left = True | ||
40 | - for i in range(1): | ||
41 | - if left: | ||
42 | - yy+=0.00001 | ||
43 | - left=False | ||
44 | - | ||
45 | - else: | ||
46 | - yy-=0.00001 | ||
47 | - left=True | ||
48 | - bbox = bbox.format(yy) | ||
49 | - sql = "SELECT geom FROM {} WHERE geom && 'BOX3D({})'::box3d limit 100000".format(table, bbox) | ||
50 | - time1=time.time() | ||
51 | - dd = ses.execute(sql) | ||
52 | - for x in dd: | ||
53 | - dddd = x | ||
54 | - print(multiprocessing.current_process(),time.time()-time1) | ||
55 | - ses.close() | ||
56 | -# query_thread() | ||
57 | if __name__ == '__main__': | 26 | if __name__ == '__main__': |
58 | - # kk="PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxkbWFwIHByb2plY3RuYW1lPSJ3bXRzdGVzdCIgdmVyc2lvbj0iNC4wIj4KICA8cHJvamVjdENycz4KICAgIDxzcGF0aWFscmVmc3lzPgogICAgICA8d2t0Pjwvd2t0PgogICAgICA8cHJvajQ+PC9wcm9qND4KICAgICAgPHNyaWQ+NDQ5MDwvc3JpZD4KICAgICAgPGRlc2NyaXB0aW9uLz4KICAgICAgPHByb2plY3Rpb25hY3JvbnltLz4KICAgIDwvc3BhdGlhbHJlZnN5cz4KICA8L3Byb2plY3RDcnM+CiAgPHByb2plY3RsYXllcnM+CiAgICA8bWFwbGF5ZXIgbmFtZT0ibGF5ZXIiIGFsaWFzPSJOb25lIiB0eXBlPSIwIj4KICAgICAgPGV4dGVudD4KICAgICAgICA8eG1pbj4xMDcuNzg5ODE0OTQxODA2MTg8L3htaW4+CiAgICAgICAgPHltaW4+MTIwLjQzNTUzNjAzOTM1Njc1PC95bWluPgogICAgICAgIDx4bWF4PjEyMC40MzU1MzYwMzkzNTY3NTwveG1heD4KICAgICAgICA8eW1heD4yNS45OTk4Njg3NTc3MzcwMzM8L3ltYXg+CiAgICAgIDwvZXh0ZW50PgogICAgICA8c3R5bGU+ZGVmYXVsdDwvc3R5bGU+CiAgICAgIDxmb3JtYXQ+aW1hZ2UvcG5nPC9mb3JtYXQ+CiAgICAgIDx2ZW5kb3I+RVNSSV9WMTwvdmVuZG9yPgogICAgICA8ZGF0YXNvdXJjZT4vdXNyL2xvY2FsL2RtYXA0L2dkbWFwL19hbGxsYXllcnM8L2RhdGFzb3VyY2U+CiAgICAgIDx0aWxlTWF0cml4U2V0cz4KICAgICAgICA8dGlsZU1hdHJpeFNldD4KICAgICAgICAgIDxpZD5kZWZhdWx0PC9pZD4KICAgICAgICAgIDxjcnM+RVBTRzo6NDQ5MDwvY3JzPgogICAgICAgICAgPHRpbGVDb2xzPjI1NjwvdGlsZUNvbHM+CiAgICAgICAgICA8dGlsZVJvd3M+MjU2PC90aWxlUm93cz4KICAgICAgICAgIDxkcGk+OTY8L2RwaT4KICAgICAgICAgIDx0aWxlT3JpZ2luPgogICAgICAgICAgICA8WD40MDA8L1g+CiAgICAgICAgICAgIDxZPi00MDA8L1k+CiAgICAgICAgICA8L3RpbGVPcmlnaW4+CiAgICAgICAgICA8bGV2ZWxzPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjA8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU5MDk5NTE4Ni4xMjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjQwNjI1MDAwMDAwNTk0ODg8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MTwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+Mjk1NDk3NTkzLjA2PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuNzAzMTI1MDAwMDAyOTc0NDwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4yPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xNDc3NDg3OTYuNTM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4zNTE1NjI1MDAwMDE0ODcyPC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjM8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjczODc0Mzk4LjI2NTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjE3NTc4MTI1MDAwMDc0MzY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MzY5MzcxOTkuMTMyNTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjA4Nzg5MDYyNTAwMDM3MTg8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NTwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MTg0Njg1OTkuNTY2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wNDM5NDUzMTI1MDAxODU5PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjY8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjkyMzQyOTkuNzgzMTI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDIxOTcyNjU2MjUwMDkyOTU8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NzwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NDYxNzE0OS44OTE1NjI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDEwOTg2MzI4MTI1MDQ2NDc1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjg8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjIzMDg1NzQuOTQ1NzgxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDU0OTMxNjQwNjI1MjMyMzc1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjk8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjExNTQyODcuNDcyODkwNjI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDAyNzQ2NTgyMDMxMjYxNjE4NzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xMDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NTc3MTQzLjczNjQ0NTMxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDEzNzMyOTEwMTU2MzA4MDk0PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjExPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4yODg1NzEuODY4MjIyNjU2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDA2ODY2NDU1MDc4MTU0MDQ3PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjEyPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xNDQyODUuOTM0MTExMzI4MTM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDAzNDMzMjI3NTM5MDc3MDIzNDwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xMzwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NzIxNDIuOTY3MDU1NjY0MDY8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDAxNzE2NjEzNzY5NTM4NTExNzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xNDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MzYwNzEuNDgzNTI3ODMyMDM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+OC41ODMwNjg4NDc2OTI1NTllLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE1PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xODAzNS43NDE3NjM5MTYwMTY8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+NC4yOTE1MzQ0MjM4NDYyNzllLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE2PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj45MDE3Ljg3MDg4MTk1ODAwODwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4yLjE0NTc2NzIxMTkyMzEzOTZlLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE3PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj40NTA4LjkzNTQ0MDk3OTAwNDwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjA3Mjg4MzYwNTk2MTU2OThlLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE4PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4yMjU0LjQ2NzcyMDQ4OTUwMjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj41LjM2NDQxODAyOTgwNzg0OWUtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MTk8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjExMjcuMjMzODYwMjQ0NzUxPC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjIuNjgyMjA5MDE0OTAzOTI0NmUtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MjA8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU2My42MTY5MzAxMjIzNzU1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjEuMzQxMTA0NTA3NDUxOTYyM2UtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICA8L2xldmVscz4KICAgICAgICA8L3RpbGVNYXRyaXhTZXQ+CiAgICAgIDwvdGlsZU1hdHJpeFNldHM+CiAgICA8L21hcGxheWVyPgogIDwvcHJvamVjdGxheWVycz4KPC9kbWFwPg==" | ||
59 | - # kk="PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxkbWFwIHByb2plY3RuYW1lPSJ3bXRzdGVzdCIgdmVyc2lvbj0iNC4wIj4KICA8cHJvamVjdENycz4KICAgIDxzcGF0aWFscmVmc3lzPgogICAgICA8d2t0Pjwvd2t0PgogICAgICA8cHJvajQ+PC9wcm9qND4KICAgICAgPHNyaWQ+NDQ5MDwvc3JpZD4KICAgICAgPGRlc2NyaXB0aW9uLz4KICAgICAgPHByb2plY3Rpb25hY3JvbnltLz4KICAgIDwvc3BhdGlhbHJlZnN5cz4KICA8L3Byb2plY3RDcnM+CiAgPHByb2plY3RsYXllcnM+CiAgICA8bWFwbGF5ZXIgbmFtZT0ibGF5ZXIiIGFsaWFzPSJOb25lIiB0eXBlPSIwIj4KICAgICAgPGV4dGVudD4KICAgICAgICA8eG1pbj4xMDcuNzg5ODE0OTQxODA2MTg8L3htaW4+CiAgICAgICAgPHltaW4+MTIwLjQzNTUzNjAzOTM1Njc1PC95bWluPgogICAgICAgIDx4bWF4PjEyMC40MzU1MzYwMzkzNTY3NTwveG1heD4KICAgICAgICA8eW1heD4yNS45OTk4Njg3NTc3MzcwMzM8L3ltYXg+CiAgICAgIDwvZXh0ZW50PgogICAgICA8c3R5bGU+ZGVmYXVsdDwvc3R5bGU+CiAgICAgIDxmb3JtYXQ+aW1hZ2UvcG5nPC9mb3JtYXQ+CiAgICAgIDx2ZW5kb3I+RVNSSV9WMTwvdmVuZG9yPgogICAgICA8ZGF0YXNvdXJjZT4vdXNyL2xvY2FsL2RtYXA0L2dkbWFwL19hbGxsYXllcnM8L2RhdGFzb3VyY2U+CiAgICAgIDx0aWxlTWF0cml4U2V0cz4KICAgICAgICA8dGlsZU1hdHJpeFNldD4KICAgICAgICAgIDxpZD5kZWZhdWx0PC9pZD4KICAgICAgICAgIDxjcnM+RVBTRzo6NDQ5MDwvY3JzPgogICAgICAgICAgPHRpbGVDb2xzPjI1NjwvdGlsZUNvbHM+CiAgICAgICAgICA8dGlsZVJvd3M+MjU2PC90aWxlUm93cz4KICAgICAgICAgIDxkcGk+OTY8L2RwaT4KICAgICAgICAgIDx0aWxlT3JpZ2luPgogICAgICAgICAgICA8WD40MDA8L1g+CiAgICAgICAgICAgIDxZPi00MDA8L1k+CiAgICAgICAgICA8L3RpbGVPcmlnaW4+CiAgICAgICAgICA8bGV2ZWxzPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjA8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU5MDk5NTE4Ni4xMjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjQwNjI1MDAwMDAwNTk0ODg8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MTwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+Mjk1NDk3NTkzLjA2PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuNzAzMTI1MDAwMDAyOTc0NDwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4yPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xNDc3NDg3OTYuNTM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4zNTE1NjI1MDAwMDE0ODcyPC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjM8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjczODc0Mzk4LjI2NTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjE3NTc4MTI1MDAwMDc0MzY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MzY5MzcxOTkuMTMyNTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjA4Nzg5MDYyNTAwMDM3MTg8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NTwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MTg0Njg1OTkuNTY2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wNDM5NDUzMTI1MDAxODU5PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjY8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjkyMzQyOTkuNzgzMTI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDIxOTcyNjU2MjUwMDkyOTU8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NzwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NDYxNzE0OS44OTE1NjI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDEwOTg2MzI4MTI1MDQ2NDc1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjg8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjIzMDg1NzQuOTQ1NzgxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDU0OTMxNjQwNjI1MjMyMzc1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjk8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjExNTQyODcuNDcyODkwNjI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDAyNzQ2NTgyMDMxMjYxNjE4NzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xMDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NTc3MTQzLjczNjQ0NTMxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDEzNzMyOTEwMTU2MzA4MDk0PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjExPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4yODg1NzEuODY4MjIyNjU2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDA2ODY2NDU1MDc4MTU0MDQ3PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjEyPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xNDQyODUuOTM0MTExMzI4MTM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDAzNDMzMjI3NTM5MDc3MDIzNDwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xMzwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NzIxNDIuOTY3MDU1NjY0MDY8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDAxNzE2NjEzNzY5NTM4NTExNzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xNDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MzYwNzEuNDgzNTI3ODMyMDM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+OC41ODMwNjg4NDc2OTI1NTllLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE1PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xODAzNS43NDE3NjM5MTYwMTY8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+NC4yOTE1MzQ0MjM4NDYyNzllLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE2PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj45MDE3Ljg3MDg4MTk1ODAwODwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4yLjE0NTc2NzIxMTkyMzEzOTZlLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE3PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj40NTA4LjkzNTQ0MDk3OTAwNDwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjA3Mjg4MzYwNTk2MTU2OThlLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE4PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4yMjU0LjQ2NzcyMDQ4OTUwMjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj41LjM2NDQxODAyOTgwNzg0OWUtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MTk8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjExMjcuMjMzODYwMjQ0NzUxPC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjIuNjgyMjA5MDE0OTAzOTI0NmUtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MjA8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU2My42MTY5MzAxMjIzNzU1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjEuMzQxMTA0NTA3NDUxOTYyM2UtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICA8L2xldmVscz4KICAgICAgICA8L3RpbGVNYXRyaXhTZXQ+CiAgICAgIDwvdGlsZU1hdHJpeFNldHM+CiAgICA8L21hcGxheWVyPgogIDwvcHJvamVjdGxheWVycz4KPC9kbWFwPg==" | ||
60 | - # kk="PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxkbWFwIHByb2plY3RuYW1lPSJ0bXN0ZXN0IiB2ZXJzaW9uPSI0LjAiPgogIDxwcm9qZWN0Q3JzPgogICAgPHNwYXRpYWxyZWZzeXM+CiAgICAgIDx3a3Q+PC93a3Q+CiAgICAgIDxwcm9qND48L3Byb2o0PgogICAgICA8c3JpZD40NDkwPC9zcmlkPgogICAgICA8ZGVzY3JpcHRpb24vPgogICAgICA8cHJvamVjdGlvbmFjcm9ueW0vPgogICAgPC9zcGF0aWFscmVmc3lzPgogIDwvcHJvamVjdENycz4KICA8cHJvamVjdGxheWVycz4KICAgIDxtYXBsYXllciBuYW1lPSJsYXllciIgYWxpYXM9Ik5vbmUiIHR5cGU9IjMiPgogICAgICA8ZXh0ZW50PgogICAgICAgIDx4bWluPjEwNy43ODk4MTQ5NDE4MDYxODwveG1pbj4KICAgICAgICA8eW1pbj4xMjAuNDM1NTM2MDM5MzU2NzU8L3ltaW4+CiAgICAgICAgPHhtYXg+MTIwLjQzNTUzNjAzOTM1Njc1PC94bWF4PgogICAgICAgIDx5bWF4PjI1Ljk5OTg2ODc1NzczNzAzMzwveW1heD4KICAgICAgPC9leHRlbnQ+CiAgICAgIDxzdHlsZT5kZWZhdWx0PC9zdHlsZT4KICAgICAgPGZvcm1hdD5pbWFnZS9wbmc8L2Zvcm1hdD4KICAgICAgPHZlbmRvcj5RR0lTPC92ZW5kb3I+CiAgICAgIDxkYXRhc291cmNlPi91c3IvbG9jYWwvZG1hcDQvcWdpczwvZGF0YXNvdXJjZT4KICAgIDwvbWFwbGF5ZXI+CiAgPC9wcm9qZWN0bGF5ZXJzPgo8L2RtYXA+" | ||
61 | - # kk="PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxkbWFwIHByb2plY3RuYW1lPSJ0bXN0ZXN0IiB2ZXJzaW9uPSI0LjAiPgogIDxwcm9qZWN0Q3JzPgogICAgPHNwYXRpYWxyZWZzeXM+CiAgICAgIDx3a3Q+PC93a3Q+CiAgICAgIDxwcm9qND48L3Byb2o0PgogICAgICA8c3JpZD40NDkwPC9zcmlkPgogICAgICA8ZGVzY3JpcHRpb24vPgogICAgICA8cHJvamVjdGlvbmFjcm9ueW0vPgogICAgPC9zcGF0aWFscmVmc3lzPgogIDwvcHJvamVjdENycz4KICA8cHJvamVjdGxheWVycz4KICAgIDxtYXBsYXllciBuYW1lPSJsYXllciIgYWxpYXM9IiIgdHlwZT0iMyI+CiAgICAgIDxleHRlbnQ+CiAgICAgICAgPHhtaW4+MTA3Ljc4OTgxNDk0MTgwNjE4PC94bWluPgogICAgICAgIDx5bWluPjEyMC40MzU1MzYwMzkzNTY3NTwveW1pbj4KICAgICAgICA8eG1heD4xMjAuNDM1NTM2MDM5MzU2NzU8L3htYXg+CiAgICAgICAgPHltYXg+MjUuOTk5ODY4NzU3NzM3MDMzPC95bWF4PgogICAgICA8L2V4dGVudD4KICAgICAgPHN0eWxlPmRlZmF1bHQ8L3N0eWxlPgogICAgICA8Zm9ybWF0PmltYWdlL3BuZzwvZm9ybWF0PgogICAgICA8dmVuZG9yPlFHSVM8L3ZlbmRvcj4KICAgICAgPGRhdGFzb3VyY2U+L3Vzci9sb2NhbC9kbWFwNC9xZ2lzPC9kYXRhc291cmNlPgogICAgPC9tYXBsYXllcj4KICA8L3Byb2plY3RsYXllcnM+CjwvZG1hcD4=" | ||
62 | - # print(str(base64.b64decode(kk), "utf-8")) | ||
63 | - # daf=0 | ||
64 | - | ||
65 | - # zoo: KazooClient = KazooClient(hosts="172.26.99.168:2181", timeout=1) | ||
66 | - # zoo.start() | ||
67 | - # while 1: | ||
68 | - # time.sleep(1) | ||
69 | - # print(zoo.connected) | ||
70 | - # print(zoo.get_children("/rpc")) | ||
71 | - | ||
72 | - # fn = "PG: user=postgres password=chinadci host=172.26.99.160 port=5432 dbname=ceshi " | ||
73 | - # driver = ogr.GetDriverByName("PostgreSQL") | ||
74 | - # if driver is None: | ||
75 | - # raise Exception("打开PostgreSQL驱动失败,可能是当前GDAL未支持PostgreSQL驱动!") | ||
76 | - # ds = driver.Open(fn, 1) | ||
77 | - # | ||
78 | - # layer:Layer = ds.GetLayerByName("shiyqzd_500_bdc") | ||
79 | - | ||
80 | - | ||
81 | - driver2 = ogr.GetDriverByName("ESRI Shapefile") | ||
82 | - data_source: DataSource = driver2.CreateDataSource("H://t3.shp") | ||
83 | - | ||
84 | - | ||
85 | - fid = layer.GetFIDColumn() | ||
86 | - pg_layer: Layer = data_source.CreateLayer("t", layer.GetSpatialRef(), layer.GetGeomType(),["ENCODING=GBK"]) | ||
87 | - | ||
88 | - #可能有问题,不支持binary | ||
89 | - schema = [sche for sche in layer.schema if not sche.name.__eq__(fid)] | ||
90 | - | ||
91 | - schema_chage = [] | ||
92 | - for sche in schema: | ||
93 | - ss :FieldDefn = sche | ||
94 | - if ss.GetType() == ogr.OFTBinary : | ||
95 | - print(ss.name) | ||
96 | - ss.SetType(ogr.OFTInteger) | ||
97 | - schema_chage.append(ss) | ||
98 | 27 | ||
99 | - pg_layer.CreateFields(schema_chage) | ||
100 | 28 | ||
29 | + fn = "PG: user=postgres password=chinadci host=172.26.60.101 port=5432 dbname=ceshi " | ||
30 | + driver = ogr.GetDriverByName("PostgreSQL") | ||
31 | + if driver is None: | ||
32 | + raise Exception("打开PostgreSQL驱动失败,可能是当前GDAL未支持PostgreSQL驱动!") | ||
33 | + ds :DataSource= driver.Open(fn, 1) | ||
34 | + if ds is None: | ||
35 | + raise Exception("打开数据源失败!") | ||
101 | 36 | ||
102 | - count =0 | ||
103 | - for feature in layer: | ||
104 | - pg_layer.CreateFeature(feature) | ||
105 | - count+=1 | ||
106 | - if count==1000: | ||
107 | - break | 37 | + for i in range(1,13): |
38 | + tn = "t{}".format(i) | ||
39 | + layer : Layer = ds.GetLayerByName(tn) | ||
108 | 40 | ||
109 | - data_source.Destroy() | ||
41 | + print(layer.GetGeomType()) |
@@ -2,3 +2,304 @@ | @@ -2,3 +2,304 @@ | ||
2 | #author: 4N | 2 | #author: 4N |
3 | #createtime: 2022/3/8 | 3 | #createtime: 2022/3/8 |
4 | #email: nheweijun@sina.com | 4 | #email: nheweijun@sina.com |
5 | + | ||
6 | + | ||
7 | +from osgeo import ogr | ||
8 | +from osgeo.ogr import * | ||
9 | +import math | ||
10 | +import os | ||
11 | +os.environ["CUDA_VISIBLE_DEVICES"] = "-1" | ||
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 | ||
25 | + | ||
26 | + | ||
27 | +class ShapeUtil: | ||
28 | + | ||
29 | + driver = ogr.GetDriverByName("ESRI Shapefile") | ||
30 | + | ||
31 | + @classmethod | ||
32 | + def create_by_layer(cls,path,layer:Layer): | ||
33 | + data_source: DataSource = cls.driver.CreateDataSource(path) | ||
34 | + data_source.CopyLayer(layer,layer.GetName()) | ||
35 | + data_source.Destroy() | ||
36 | + | ||
37 | + @classmethod | ||
38 | + def create_by_scheme(cls,path,name,sr,geo_type,scheme,features): | ||
39 | + data_source: DataSource = cls.driver.CreateDataSource(path) | ||
40 | + layer :Layer = data_source.CreateLayer(name, sr, geo_type) | ||
41 | + if scheme: | ||
42 | + layer.CreateFields(scheme) | ||
43 | + for feature in features: | ||
44 | + layer.CreateFeature(feature) | ||
45 | + data_source.Destroy() | ||
46 | + | ||
47 | + @classmethod | ||
48 | + def create_point(cls,path,name,point): | ||
49 | + data_source: DataSource = cls.driver.CreateDataSource(path) | ||
50 | + layer :Layer = data_source.CreateLayer(name, None, ogr.wkbPoint) | ||
51 | + | ||
52 | + feat_new = ogr.Feature(layer.GetLayerDefn()) | ||
53 | + feat_new.SetGeometry(point) | ||
54 | + layer.CreateFeature(feat_new) | ||
55 | + data_source.Destroy() | ||
56 | + | ||
57 | + | ||
58 | +class ShapeData: | ||
59 | + | ||
60 | + def __init__(self,path): | ||
61 | + driver: Driver = ogr.GetDriverByName("ESRI Shapefile") | ||
62 | + self.ds: DataSource = driver.Open(path, 1) | ||
63 | + if not self.ds: | ||
64 | + raise Exception("打开数据失败!") | ||
65 | + self.layer: Layer = self.ds.GetLayer(0) | ||
66 | + | ||
67 | + | ||
68 | + def get_polygons(self): | ||
69 | + | ||
70 | + polygons = [] | ||
71 | + for feature in self.layer: | ||
72 | + f:Feature = feature | ||
73 | + geom : Geometry = f.GetGeometryRef() | ||
74 | + if geom.GetGeometryType() == 3 or geom.GetGeometryType() == -2147483645: | ||
75 | + polygons.append(geom) | ||
76 | + if geom.GetGeometryType() == 6 or geom.GetGeometryType() == -2147483642: | ||
77 | + for i in range(geom.GetGeometryCount()): | ||
78 | + polygons.append(geom.GetGeometryRef(i)) | ||
79 | + return polygons | ||
80 | + | ||
81 | + def close(self): | ||
82 | + self.ds.Destroy() | ||
83 | + | ||
84 | + | ||
85 | +class Zonghe: | ||
86 | + | ||
87 | + data:ShapeData | ||
88 | + area_threshold = 10.0 | ||
89 | + buffer_threshold = 100.0 | ||
90 | + | ||
91 | + def __init__(self,data): | ||
92 | + self.data = data | ||
93 | + | ||
94 | + | ||
95 | + | ||
96 | + #只处理Polygon,MultiPolygon要拆开 | ||
97 | + def get_polygon_reprecent_point(self,polygon:Geometry): | ||
98 | + | ||
99 | + polygon_area = polygon.GetArea() | ||
100 | + | ||
101 | + polygon_env = polygon.GetEnvelope() | ||
102 | + | ||
103 | + line_length = max(polygon_env[1]-polygon_env[0],polygon_env[3]-polygon_env[2]) | ||
104 | + | ||
105 | + center:Geometry = polygon.Centroid() | ||
106 | + if polygon.Contains(center): | ||
107 | + return center | ||
108 | + | ||
109 | + | ||
110 | + left_area = 0 | ||
111 | + right_area = polygon_area | ||
112 | + | ||
113 | + left_or_right = None | ||
114 | + fen = False | ||
115 | + | ||
116 | + if polygon.GetGeometryCount() == 1: | ||
117 | + polygon_line = ogr.ForceToLineString(polygon) | ||
118 | + # 有孔Polygon | ||
119 | + else: | ||
120 | + polygon_line = ogr.ForceToLineString(polygon.GetGeometryRef(0)) | ||
121 | + | ||
122 | + # print(len(polygon_line.GetPoints())) | ||
123 | + point_i = 0 | ||
124 | + | ||
125 | + line = None | ||
126 | + next_point = polygon_line.GetPoint(point_i) | ||
127 | + last_point = None | ||
128 | + last_last_point = None | ||
129 | + | ||
130 | + angle = [] | ||
131 | + | ||
132 | + calculate_times = 0 | ||
133 | + | ||
134 | + while abs(left_area - right_area) > (polygon_area / self.area_threshold): | ||
135 | + # print(calculate_times) | ||
136 | + calculate_times += 1 | ||
137 | + | ||
138 | + line,other_point = self.get_line(center.GetX(),center.GetY(),next_point[0],next_point[1],line_length) | ||
139 | + | ||
140 | + clip_geom:Geometry = polygon.Difference(line.Buffer(line_length/self.buffer_threshold)) | ||
141 | + | ||
142 | + | ||
143 | + if clip_geom.GetGeometryType() == 3 or clip_geom.GetGeometryType() == -2147483645: | ||
144 | + | ||
145 | + cl = ogr.ForceToLineString(clip_geom) | ||
146 | + p1 = cl.GetPoint(0) | ||
147 | + p2 = cl.GetPoint(1) | ||
148 | + tp = [(p1[0] + p2[0])/2.0, (p1[1] + p2[1])/2.0] | ||
149 | + # clip_geom_center = clip_geom.Centroid() | ||
150 | + | ||
151 | + | ||
152 | + side_value = self.side(center,other_point,self.creat_point(tp)) | ||
153 | + if side_value > 0: | ||
154 | + left_area = clip_geom.GetArea() | ||
155 | + right_area = 0 | ||
156 | + else: | ||
157 | + right_area = clip_geom.GetArea() | ||
158 | + left_area = 0 | ||
159 | + | ||
160 | + | ||
161 | + | ||
162 | + else: | ||
163 | + | ||
164 | + left_area = 0 | ||
165 | + right_area = 0 | ||
166 | + | ||
167 | + for gi in range(clip_geom.GetGeometryCount()): | ||
168 | + clip_geom_i :Geometry = clip_geom.GetGeometryRef(gi) | ||
169 | + clip_geom_i_center = clip_geom_i.Centroid() | ||
170 | + side_value = self.side(center, other_point, clip_geom_i_center) | ||
171 | + | ||
172 | + if side_value > 0: | ||
173 | + left_area += clip_geom_i.GetArea() | ||
174 | + else: | ||
175 | + right_area += clip_geom_i.GetArea() | ||
176 | + | ||
177 | + | ||
178 | + print(left_area,right_area) | ||
179 | + | ||
180 | + last_last_point = last_point | ||
181 | + last_point = next_point | ||
182 | + left_or_right = 1 if left_area > right_area else -1 | ||
183 | + | ||
184 | + | ||
185 | + # 进入二分法步骤 | ||
186 | + if fen: | ||
187 | + | ||
188 | + alternate:Geometry = ogr.Geometry(ogr.wkbPoint) | ||
189 | + alternate.AddPoint(angle[0][0],angle[0][1]) | ||
190 | + # print(angle) | ||
191 | + alternate_side = self.side(center, other_point, alternate) | ||
192 | + print(alternate_side) | ||
193 | + if left_or_right * alternate_side > 0: | ||
194 | + angle = [angle[0],next_point] | ||
195 | + next_point = ((next_point[0]+angle[0][0])/2.0,(next_point[1]+angle[0][1])/2.0) | ||
196 | + | ||
197 | + # print(abs(next_point[0]-angle[0][0])) | ||
198 | + else: | ||
199 | + angle = [angle[1],next_point] | ||
200 | + next_point = ((next_point[0]+angle[1][0])/2.0,(next_point[1]+angle[1][1])/2.0) | ||
201 | + | ||
202 | + # print(abs(next_point[0] - angle[1][0])) | ||
203 | + | ||
204 | + else: | ||
205 | + # print(point_i) | ||
206 | + point_i += 1 | ||
207 | + next_point = polygon_line.GetPoint(point_i) | ||
208 | + | ||
209 | + next_point_side = self.side(center, other_point, self.creat_point(next_point)) | ||
210 | + | ||
211 | + if left_or_right * next_point_side > 0 : | ||
212 | + pass | ||
213 | + else: | ||
214 | + next_point = ((last_point[0]+last_last_point[0])/2.0,(last_point[1]+last_last_point[1])/2.0) | ||
215 | + angle = [last_last_point,last_point] | ||
216 | + fen = True | ||
217 | + | ||
218 | + print(calculate_times) | ||
219 | + | ||
220 | + point_intersection:Geometry = line.Intersection(polygon_line) | ||
221 | + | ||
222 | + xlist = [] | ||
223 | + ylist = [] | ||
224 | + for i in range(point_intersection.GetGeometryCount()): | ||
225 | + pi = point_intersection.GetGeometryRef(i) | ||
226 | + xlist.append(pi.GetX()) | ||
227 | + ylist.append(pi.GetY()) | ||
228 | + | ||
229 | + reprecent_point = [(min(xlist)+max(xlist))/2.0,(min(ylist)+max(ylist))/2.0] | ||
230 | + | ||
231 | + return self.creat_point(reprecent_point) | ||
232 | + | ||
233 | + | ||
234 | + | ||
235 | + def get_line(self,x0,y0,x1,y1,len_size): | ||
236 | + | ||
237 | + line: Geometry = ogr.Geometry(ogr.wkbLineString) | ||
238 | + line.AddPoint(x0, y0) | ||
239 | + x2 = x0 + len_size | ||
240 | + | ||
241 | + if x1 != x0: | ||
242 | + y2 = ((y1-y0)*(x2-x0))/(x1-x0) + y0 | ||
243 | + else: | ||
244 | + x2 = x0 | ||
245 | + y2 = y0 + len_size | ||
246 | + line.AddPoint(x2, y2) | ||
247 | + | ||
248 | + other_point = ogr.Geometry(ogr.wkbPoint) | ||
249 | + other_point.AddPoint(x2, y2) | ||
250 | + | ||
251 | + return line, other_point | ||
252 | + def creat_point(self,tuple): | ||
253 | + p: Geometry = ogr.Geometry(ogr.wkbPoint) | ||
254 | + p.AddPoint(tuple[0], tuple[1]) | ||
255 | + return p | ||
256 | + | ||
257 | + | ||
258 | + | ||
259 | + def side(self,A,B,P): | ||
260 | + | ||
261 | + | ||
262 | + side = (B.GetX() - A.GetX()) * (P.GetY() - A.GetY()) - (B.GetY() - A.GetY()) * (P.GetX() - A.GetX()) | ||
263 | + return side | ||
264 | + | ||
265 | + | ||
266 | + | ||
267 | + | ||
268 | + def process(self): | ||
269 | + polygons = self.data.get_polygons() | ||
270 | + for poly in polygons: | ||
271 | + reprecent_point = self.get_polygon_reprecent_point(poly) | ||
272 | + print(reprecent_point) | ||
273 | + | ||
274 | + | ||
275 | + | ||
276 | +if __name__ == '__main__': | ||
277 | + | ||
278 | + # sd = ShapeData(r"J:\Data\矢量数据\佛山\制图综合.shp") | ||
279 | + # print(sd.get_polygons()[0]) | ||
280 | + # sd.close() | ||
281 | + | ||
282 | + driver: Driver = ogr.GetDriverByName("ESRI Shapefile") | ||
283 | + ds: DataSource = driver.Open(r"J:\Data\矢量数据\佛山\制图综合\t2.shp",0) | ||
284 | + | ||
285 | + layer: Layer = ds.GetLayer(0) | ||
286 | + | ||
287 | + polygons = [] | ||
288 | + for feature in layer: | ||
289 | + f:Feature = feature | ||
290 | + geom : Geometry = f.GetGeometryRef() | ||
291 | + if geom.GetGeometryType() == 3 or geom.GetGeometryType() == -2147483645: | ||
292 | + polygons.append(geom) | ||
293 | + if geom.GetGeometryType() == 6 or geom.GetGeometryType() == -2147483642: | ||
294 | + for i in range(geom.GetGeometryCount()): | ||
295 | + polygons.append(geom.GetGeometryRef(i)) | ||
296 | + del ds | ||
297 | + zh = Zonghe("d") | ||
298 | + pre = zh.get_polygon_reprecent_point(polygons[0]) | ||
299 | + print(pre) | ||
300 | + | ||
301 | + result="J:\Data\矢量数据\佛山\制图综合\zhresult.shp" | ||
302 | + print(pre) | ||
303 | + | ||
304 | + ShapeUtil.create_point(result,"zh",pre) | ||
305 | + |
@@ -54,6 +54,35 @@ class ShapeUtil: | @@ -54,6 +54,35 @@ class ShapeUtil: | ||
54 | layer.CreateFeature(feat_new) | 54 | layer.CreateFeature(feat_new) |
55 | data_source.Destroy() | 55 | data_source.Destroy() |
56 | 56 | ||
57 | + @classmethod | ||
58 | + def create_shp_fromwkts(cls,path,name,wkts): | ||
59 | + | ||
60 | + geo_type = None | ||
61 | + geoms = [] | ||
62 | + for wkt in wkts: | ||
63 | + geom : Geometry = ogr.CreateGeometryFromWkt(wkt) | ||
64 | + if geo_type is None: | ||
65 | + geo_type = geom.GetGeometryType() | ||
66 | + geoms.append(geom) | ||
67 | + | ||
68 | + if os.path.exists(path): | ||
69 | + | ||
70 | + pre_name = ".".join(path.split(".")[0:-1]) | ||
71 | + for bac in ["dbf","prj","cpg","shp","shx","sbn","sbx"]: | ||
72 | + try: | ||
73 | + os.remove(pre_name+"."+bac) | ||
74 | + except Exception as e: | ||
75 | + pass | ||
76 | + | ||
77 | + data_source: DataSource = cls.driver.CreateDataSource(path) | ||
78 | + layer :Layer = data_source.CreateLayer(name, None, geo_type) | ||
79 | + | ||
80 | + for geom in geoms: | ||
81 | + feat_new = ogr.Feature(layer.GetLayerDefn()) | ||
82 | + feat_new.SetGeometry(geom) | ||
83 | + layer.CreateFeature(feat_new) | ||
84 | + data_source.Destroy() | ||
85 | + | ||
57 | 86 | ||
58 | class ShapeData: | 87 | class ShapeData: |
59 | 88 | ||
@@ -85,7 +114,7 @@ class ShapeData: | @@ -85,7 +114,7 @@ class ShapeData: | ||
85 | class Zonghe: | 114 | class Zonghe: |
86 | 115 | ||
87 | data:ShapeData | 116 | data:ShapeData |
88 | - area_threshold = 10.0 | 117 | + area_threshold = 20.0 |
89 | buffer_threshold = 100.0 | 118 | buffer_threshold = 100.0 |
90 | 119 | ||
91 | def __init__(self,data): | 120 | def __init__(self,data): |
@@ -96,174 +125,363 @@ class Zonghe: | @@ -96,174 +125,363 @@ class Zonghe: | ||
96 | #只处理Polygon,MultiPolygon要拆开 | 125 | #只处理Polygon,MultiPolygon要拆开 |
97 | def get_polygon_reprecent_point(self,polygon:Geometry): | 126 | def get_polygon_reprecent_point(self,polygon:Geometry): |
98 | 127 | ||
99 | - polygon_area = polygon.GetArea() | ||
100 | - | ||
101 | polygon_env = polygon.GetEnvelope() | 128 | polygon_env = polygon.GetEnvelope() |
102 | 129 | ||
103 | line_length = max(polygon_env[1]-polygon_env[0],polygon_env[3]-polygon_env[2]) | 130 | line_length = max(polygon_env[1]-polygon_env[0],polygon_env[3]-polygon_env[2]) |
104 | 131 | ||
132 | + | ||
133 | + short_length = min(polygon_env[1]-polygon_env[0],polygon_env[3]-polygon_env[2]) | ||
134 | + | ||
105 | center:Geometry = polygon.Centroid() | 135 | center:Geometry = polygon.Centroid() |
136 | + | ||
137 | + # 提前return | ||
106 | if polygon.Contains(center): | 138 | if polygon.Contains(center): |
107 | return center | 139 | return center |
108 | 140 | ||
141 | + last_state = None | ||
142 | + line = None | ||
143 | + calculate_time = 0 | ||
144 | + direction = self.get_direction(polygon, center, line_length) | ||
145 | + in_hole = False | ||
146 | + in_hole_line = None | ||
109 | 147 | ||
110 | - left_area = 0 | ||
111 | - right_area = polygon_area | ||
112 | - | ||
113 | - left_or_right = None | ||
114 | - fen = False | ||
115 | 148 | ||
149 | + #无孔Polygon | ||
116 | if polygon.GetGeometryCount() == 1: | 150 | if polygon.GetGeometryCount() == 1: |
117 | polygon_line = ogr.ForceToLineString(polygon) | 151 | polygon_line = ogr.ForceToLineString(polygon) |
118 | - # 有孔Polygon | 152 | + |
153 | + # 有孔Polygon,要分2种情况 | ||
119 | else: | 154 | else: |
120 | polygon_line = ogr.ForceToLineString(polygon.GetGeometryRef(0)) | 155 | polygon_line = ogr.ForceToLineString(polygon.GetGeometryRef(0)) |
156 | + for i in range(1,polygon.GetGeometryCount()): | ||
157 | + hole_line = polygon.GetGeometryRef(i) | ||
158 | + hole_polygon : Geometry = ogr.ForceToPolygon(hole_line) | ||
159 | + if hole_polygon.Contains(center): | ||
160 | + in_hole = True | ||
161 | + direction = range(0,190,10) | ||
162 | + in_hole_line = ogr.ForceToLineString(hole_line) | ||
163 | + print("in_hole") | ||
121 | 164 | ||
122 | - # print(len(polygon_line.GetPoints())) | ||
123 | - point_i = 0 | ||
124 | - | ||
125 | - line = None | ||
126 | - next_point = polygon_line.GetPoint(point_i) | ||
127 | - last_point = None | ||
128 | - last_last_point = None | ||
129 | - | ||
130 | - angle = [] | ||
131 | - | ||
132 | - calculate_times = 0 | ||
133 | - | ||
134 | - while abs(left_area - right_area) > (polygon_area / self.area_threshold): | ||
135 | - # print(calculate_times) | ||
136 | - calculate_times += 1 | ||
137 | - | ||
138 | - line,other_point = self.get_line(center.GetX(),center.GetY(),next_point[0],next_point[1],line_length) | ||
139 | 165 | ||
140 | - clip_geom:Geometry = polygon.Difference(line.Buffer(line_length/self.buffer_threshold)) | ||
141 | 166 | ||
167 | + for angle in direction: | ||
142 | 168 | ||
143 | - if clip_geom.GetGeometryType() == 3 or clip_geom.GetGeometryType() == -2147483645: | ||
144 | - | ||
145 | - cl = ogr.ForceToLineString(clip_geom) | ||
146 | - p1 = cl.GetPoint(0) | ||
147 | - p2 = cl.GetPoint(1) | ||
148 | - tp = [(p1[0] + p2[0])/2.0, (p1[1] + p2[1])/2.0] | ||
149 | - # clip_geom_center = clip_geom.Centroid() | ||
150 | - | ||
151 | - | ||
152 | - side_value = self.side(center,other_point,self.creat_point(tp)) | ||
153 | - if side_value > 0: | ||
154 | - left_area = clip_geom.GetArea() | ||
155 | - right_area = 0 | ||
156 | - else: | ||
157 | - right_area = clip_geom.GetArea() | ||
158 | - left_area = 0 | 169 | + if in_hole: |
170 | + line = self.get_doubleline(center.GetX(),center.GetY(),angle,line_length) | ||
171 | + else: | ||
172 | + line = self.get_line(center.GetX(),center.GetY(),angle,line_length) | ||
159 | 173 | ||
174 | + line_buffer:Geometry = line.Buffer(line_length / self.buffer_threshold) | ||
175 | + clip_geom: Geometry = polygon.Difference(line_buffer) | ||
160 | 176 | ||
177 | + oneside_area = 0 | ||
178 | + otherside_area = 0 | ||
161 | 179 | ||
180 | + gc = clip_geom.GetGeometryCount() | ||
181 | + if gc <= 1: | ||
182 | + oneside_area = 0 | ||
183 | + otherside_area = 0 | ||
162 | else: | 184 | else: |
163 | - | ||
164 | - left_area = 0 | ||
165 | - right_area = 0 | 185 | + calculate_time += 1 |
186 | + triangle1, triangle2 = self.get_side_triangle(line, angle) | ||
166 | 187 | ||
167 | for gi in range(clip_geom.GetGeometryCount()): | 188 | for gi in range(clip_geom.GetGeometryCount()): |
168 | clip_geom_i :Geometry = clip_geom.GetGeometryRef(gi) | 189 | clip_geom_i :Geometry = clip_geom.GetGeometryRef(gi) |
169 | - clip_geom_i_center = clip_geom_i.Centroid() | ||
170 | - side_value = self.side(center, other_point, clip_geom_i_center) | 190 | + it = clip_geom_i.Intersection(triangle1) |
171 | 191 | ||
172 | - if side_value > 0: | ||
173 | - left_area += clip_geom_i.GetArea() | 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() | ||
174 | else: | 194 | else: |
175 | - right_area += clip_geom_i.GetArea() | ||
176 | - | ||
177 | - | ||
178 | - print(left_area,right_area) | 195 | + otherside_area += clip_geom_i.GetArea() |
196 | + print(oneside_area,otherside_area) | ||
197 | + if last_state is None: | ||
198 | + if oneside_area == 0 and otherside_area==0: | ||
199 | + last_state = 0 | ||
200 | + else: | ||
201 | + last_state = 1 if oneside_area < otherside_area else -1 | ||
202 | + else: | ||
203 | + if oneside_area == 0 and otherside_area==0: | ||
204 | + now_state = 0 | ||
205 | + else: | ||
206 | + now_state = 1 if oneside_area < otherside_area else -1 | ||
179 | 207 | ||
180 | - last_last_point = last_point | ||
181 | - last_point = next_point | ||
182 | - left_or_right = 1 if left_area > right_area else -1 | 208 | + if last_state* now_state < 0: |
209 | + break | ||
210 | + else: | ||
211 | + last_state = now_state | ||
183 | 212 | ||
213 | + # 提前return | ||
214 | + if in_hole: | ||
215 | + # print(line) | ||
216 | + # print(in_hole_line) | ||
217 | + point_intersection: Geometry = line.Intersection(in_hole_line) | ||
218 | + plist = [] | ||
219 | + for i in range(point_intersection.GetGeometryCount()): | ||
220 | + pi = point_intersection.GetGeometryRef(i) | ||
221 | + plist.append(pi) | ||
222 | + plist_d = [(pi,center.Distance(pi)) for pi in plist] | ||
223 | + plist_d.sort(key=lambda x:x[1]) | ||
184 | 224 | ||
185 | - # 进入二分法步骤 | ||
186 | - if fen: | 225 | + nearest_point= plist_d[0][0] |
226 | + # print(line_length) | ||
227 | + # print(short_length) | ||
228 | + # print(nearest_point) | ||
187 | 229 | ||
188 | - alternate:Geometry = ogr.Geometry(ogr.wkbPoint) | ||
189 | - alternate.AddPoint(angle[0][0],angle[0][1]) | ||
190 | - # print(angle) | ||
191 | - alternate_side = self.side(center, other_point, alternate) | ||
192 | - print(alternate_side) | ||
193 | - if left_or_right * alternate_side > 0: | ||
194 | - angle = [angle[0],next_point] | ||
195 | - next_point = ((next_point[0]+angle[0][0])/2.0,(next_point[1]+angle[0][1])/2.0) | 230 | + firt_short_length = short_length/20.0 |
231 | + # print(firt_short_length) | ||
196 | 232 | ||
197 | - # print(abs(next_point[0]-angle[0][0])) | ||
198 | - else: | ||
199 | - angle = [angle[1],next_point] | ||
200 | - next_point = ((next_point[0]+angle[1][0])/2.0,(next_point[1]+angle[1][1])/2.0) | 233 | + radline,other_point = self.get_radline(center.GetX(),center.GetY(),nearest_point.GetX(),nearest_point.GetY(),firt_short_length) |
201 | 234 | ||
202 | - # print(abs(next_point[0] - angle[1][0])) | 235 | + print(other_point) |
203 | 236 | ||
204 | - else: | ||
205 | - # print(point_i) | ||
206 | - point_i += 1 | ||
207 | - next_point = polygon_line.GetPoint(point_i) | 237 | + while not polygon.Contains(other_point): |
238 | + firt_short_length = firt_short_length / 2 | ||
239 | + radline, other_point = self.get_radline(center.GetX(), center.GetY(), nearest_point.GetX(), | ||
240 | + nearest_point.GetY(), firt_short_length) | ||
208 | 241 | ||
209 | - next_point_side = self.side(center, other_point, self.creat_point(next_point)) | 242 | + print("return hole_rep") |
210 | 243 | ||
211 | - if left_or_right * next_point_side > 0 : | ||
212 | - pass | ||
213 | - else: | ||
214 | - next_point = ((last_point[0]+last_last_point[0])/2.0,(last_point[1]+last_last_point[1])/2.0) | ||
215 | - angle = [last_last_point,last_point] | ||
216 | - fen = True | 244 | + return other_point |
217 | 245 | ||
218 | - print(calculate_times) | ||
219 | 246 | ||
220 | point_intersection:Geometry = line.Intersection(polygon_line) | 247 | point_intersection:Geometry = line.Intersection(polygon_line) |
221 | - | ||
222 | xlist = [] | 248 | xlist = [] |
223 | ylist = [] | 249 | ylist = [] |
250 | + plist = [] | ||
251 | + | ||
224 | for i in range(point_intersection.GetGeometryCount()): | 252 | for i in range(point_intersection.GetGeometryCount()): |
225 | pi = point_intersection.GetGeometryRef(i) | 253 | pi = point_intersection.GetGeometryRef(i) |
226 | xlist.append(pi.GetX()) | 254 | xlist.append(pi.GetX()) |
227 | ylist.append(pi.GetY()) | 255 | ylist.append(pi.GetY()) |
256 | + plist.append(pi) | ||
228 | 257 | ||
229 | reprecent_point = [(min(xlist)+max(xlist))/2.0,(min(ylist)+max(ylist))/2.0] | 258 | reprecent_point = [(min(xlist)+max(xlist))/2.0,(min(ylist)+max(ylist))/2.0] |
230 | 259 | ||
231 | - return self.creat_point(reprecent_point) | 260 | + reprecent_point = self.creat_point(reprecent_point) |
261 | + | ||
262 | + if not polygon.Contains(reprecent_point): | ||
263 | + plist_d = [(pi,center.Distance(pi)) for pi in plist] | ||
264 | + plist_d.sort(key=lambda x:x[1]) | ||
265 | + 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 | + | ||
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 | + | ||
278 | + | ||
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) | ||
298 | + | ||
299 | + p4: Geometry = ogr.Geometry(ogr.wkbPoint) | ||
300 | + p4.AddPoint(3, 5) | ||
301 | + mp.AddGeometry(p4) | ||
302 | + | ||
303 | + p5: Geometry = ogr.Geometry(ogr.wkbPoint) | ||
304 | + p5.AddPoint(4, 2) | ||
305 | + mp.AddGeometry(p5) | ||
306 | + | ||
307 | + p6: Geometry = ogr.Geometry(ogr.wkbPoint) | ||
308 | + | ||
309 | + p6.AddPoint(3, 1) | ||
310 | + | ||
311 | + mp.AddGeometry(p6) | ||
312 | + | ||
313 | + de = mp.DelaunayTriangulation() | ||
314 | + | ||
315 | + print(mp) | ||
316 | + | ||
317 | + for i in range(de.GetGeometryCount()): | ||
318 | + d:Geometry = de.GetGeometryRef(i) | ||
319 | + | ||
320 | + print("\""+d.ExportToWkt()+"\",") | ||
321 | + | ||
322 | + def get_line(self, x0, y0 , angle, r): | ||
232 | 323 | ||
324 | + line: Geometry = ogr.Geometry(ogr.wkbLineString) | ||
325 | + line.AddPoint(x0, y0) | ||
326 | + hudu = angle/360.0 * 2 * math.pi | ||
327 | + dx = math.sin(hudu) * r | ||
328 | + dy = math.cos(hudu) * r | ||
329 | + line.AddPoint(x0+dx, y0+dy) | ||
330 | + | ||
331 | + return line | ||
332 | + | ||
333 | + def get_doubleline(self, x0, y0 , angle, r): | ||
334 | + | ||
335 | + line: Geometry = ogr.Geometry(ogr.wkbLineString) | ||
336 | + | ||
337 | + hudu = angle/360.0 * 2 * math.pi | ||
338 | + dx = math.sin(hudu) * r | ||
339 | + dy = math.cos(hudu) * r | ||
340 | + | ||
341 | + hudu = (angle+180)/360.0 * 2 * math.pi | ||
342 | + dx2 = math.sin(hudu) * r | ||
343 | + dy2 = math.cos(hudu) * r | ||
233 | 344 | ||
345 | + line.AddPoint(x0 + dx2, y0 + dy2) | ||
346 | + line.AddPoint(x0+dx, y0+dy) | ||
234 | 347 | ||
235 | - def get_line(self,x0,y0,x1,y1,len_size): | 348 | + return line |
349 | + | ||
350 | + | ||
351 | + def get_radline(self,x0,y0,x1,y1,len_size): | ||
236 | 352 | ||
237 | line: Geometry = ogr.Geometry(ogr.wkbLineString) | 353 | line: Geometry = ogr.Geometry(ogr.wkbLineString) |
238 | line.AddPoint(x0, y0) | 354 | line.AddPoint(x0, y0) |
239 | - x2 = x0 + len_size | 355 | + tanx = (y1-y0) / (x1-x0) |
356 | + cosx = 1 / math.sqrt(1 + tanx *tanx) | ||
357 | + dx = cosx* len_size | ||
358 | + | ||
359 | + x2 = x1 + dx | ||
240 | 360 | ||
241 | if x1 != x0: | 361 | if x1 != x0: |
242 | y2 = ((y1-y0)*(x2-x0))/(x1-x0) + y0 | 362 | y2 = ((y1-y0)*(x2-x0))/(x1-x0) + y0 |
243 | else: | 363 | else: |
244 | x2 = x0 | 364 | x2 = x0 |
245 | - y2 = y0 + len_size | 365 | + y2 = y0 + dx |
246 | line.AddPoint(x2, y2) | 366 | line.AddPoint(x2, y2) |
247 | 367 | ||
248 | other_point = ogr.Geometry(ogr.wkbPoint) | 368 | other_point = ogr.Geometry(ogr.wkbPoint) |
249 | other_point.AddPoint(x2, y2) | 369 | other_point.AddPoint(x2, y2) |
250 | 370 | ||
251 | - return line, other_point | ||
252 | - def creat_point(self,tuple): | ||
253 | - p: Geometry = ogr.Geometry(ogr.wkbPoint) | ||
254 | - p.AddPoint(tuple[0], tuple[1]) | ||
255 | - return p | 371 | + return line , other_point |
372 | + | ||
373 | + def get_direction(self,polygon,center,line_length): | ||
374 | + ''' | ||
375 | + 判断旋转方向 | ||
376 | + :param polygon: | ||
377 | + :param center: | ||
378 | + :param line_length: | ||
379 | + :return: | ||
380 | + ''' | ||
381 | + | ||
382 | + line = self.get_line(center.GetX(),center.GetY(),0,line_length) | ||
383 | + line_buffer:Geometry = line.Buffer(line_length / self.buffer_threshold) | ||
384 | + clip_geom: Geometry = polygon.Difference(line_buffer) | ||
385 | + | ||
386 | + gc = clip_geom.GetGeometryCount() | ||
387 | + oneside_area = 0 | ||
388 | + otherside_area = 0 | ||
389 | + | ||
390 | + if gc <= 1: | ||
391 | + return range(0,370,10) | ||
392 | + else: | ||
393 | + triangle1, triangle2 = self.get_side_triangle(line, 0) | ||
394 | + | ||
395 | + for gi in range(clip_geom.GetGeometryCount()): | ||
396 | + clip_geom_i: Geometry = clip_geom.GetGeometryRef(gi) | ||
397 | + it = clip_geom_i.Intersection(triangle1) | ||
398 | + | ||
399 | + if clip_geom_i.Intersect(triangle1) and it.Buffer(line_length / self.buffer_threshold).Intersect( | ||
400 | + line_buffer): | ||
401 | + oneside_area += clip_geom_i.GetArea() | ||
402 | + else: | ||
403 | + otherside_area += clip_geom_i.GetArea() | ||
404 | + | ||
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) | ||
411 | + | ||
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) | ||
417 | + | ||
418 | + for gi in range(clip_geom.GetGeometryCount()): | ||
419 | + clip_geom_i: Geometry = clip_geom.GetGeometryRef(gi) | ||
420 | + it = clip_geom_i.Intersection(triangle1) | ||
421 | + | ||
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() | ||
427 | + | ||
428 | + if abs(oneside_area - otherside_area) > abs(oneside_area_contrast - otherside_area_contrast): | ||
429 | + return range(0, 370, 10) | ||
430 | + else: | ||
431 | + return range(360, -10, -10) | ||
432 | + | ||
433 | + def get_side_triangle(self,line:Geometry,angle): | ||
434 | + ''' | ||
435 | + 获取方向三角形 | ||
436 | + :param line: | ||
437 | + :param angle: | ||
438 | + :return: | ||
439 | + ''' | ||
440 | + | ||
441 | + start = line.GetPoint(0) | ||
442 | + end = line.GetPoint(1) | ||
443 | + | ||
444 | + | ||
445 | + angle_t = angle-30 | ||
446 | + hudu = angle_t/360.0 * 2 * math.pi | ||
447 | + | ||
448 | + r = line.Length() / (2*math.cos( math.pi/6)) | ||
449 | + dx = math.sin(hudu) * r | ||
450 | + dy = math.cos(hudu) * r | ||
451 | + | ||
452 | + | ||
453 | + ring1 = ogr.Geometry(ogr.wkbLinearRing) | ||
454 | + ring1.AddPoint(start[0], start[1]) | ||
455 | + ring1.AddPoint(start[0] + dx, start[1] + dy) | ||
456 | + ring1.AddPoint(end[0], end[1]) | ||
457 | + ring1.AddPoint(start[0], start[1]) | ||
458 | + triangle1 = ogr.Geometry(ogr.wkbPolygon) | ||
459 | + triangle1.AddGeometry(ring1) | ||
256 | 460 | ||
257 | 461 | ||
462 | + angle_t = angle+30 | ||
463 | + hudu = angle_t/360.0 * 2 * math.pi | ||
258 | 464 | ||
259 | - def side(self,A,B,P): | 465 | + r = line.Length() / (2*math.cos( math.pi/6)) |
260 | 466 | ||
467 | + dx = math.sin(hudu) * r | ||
468 | + dy = math.cos(hudu) * r | ||
261 | 469 | ||
262 | - side = (B.GetX() - A.GetX()) * (P.GetY() - A.GetY()) - (B.GetY() - A.GetY()) * (P.GetX() - A.GetX()) | ||
263 | - return side | 470 | + ring2 = ogr.Geometry(ogr.wkbLinearRing) |
471 | + ring2.AddPoint(start[0], start[1]) | ||
472 | + ring2.AddPoint(start[0]+dx, start[1]+dy) | ||
473 | + ring2.AddPoint(end[0], end[1]) | ||
474 | + ring2.AddPoint(start[0], start[1]) | ||
475 | + triangle2 = ogr.Geometry(ogr.wkbPolygon) | ||
476 | + triangle2.AddGeometry(ring2) | ||
264 | 477 | ||
478 | + return triangle1,triangle2 | ||
265 | 479 | ||
266 | 480 | ||
481 | + def creat_point(self,tuple): | ||
482 | + p: Geometry = ogr.Geometry(ogr.wkbPoint) | ||
483 | + p.AddPoint(tuple[0], tuple[1]) | ||
484 | + return p | ||
267 | 485 | ||
268 | def process(self): | 486 | def process(self): |
269 | polygons = self.data.get_polygons() | 487 | polygons = self.data.get_polygons() |
@@ -279,27 +497,43 @@ if __name__ == '__main__': | @@ -279,27 +497,43 @@ if __name__ == '__main__': | ||
279 | # print(sd.get_polygons()[0]) | 497 | # print(sd.get_polygons()[0]) |
280 | # sd.close() | 498 | # sd.close() |
281 | 499 | ||
282 | - driver: Driver = ogr.GetDriverByName("ESRI Shapefile") | ||
283 | - ds: DataSource = driver.Open(r"J:\Data\矢量数据\佛山\制图综合\t2.shp",0) | ||
284 | - | ||
285 | - layer: Layer = ds.GetLayer(0) | ||
286 | - | ||
287 | - polygons = [] | ||
288 | - for feature in layer: | ||
289 | - f:Feature = feature | ||
290 | - geom : Geometry = f.GetGeometryRef() | ||
291 | - if geom.GetGeometryType() == 3 or geom.GetGeometryType() == -2147483645: | ||
292 | - polygons.append(geom) | ||
293 | - if geom.GetGeometryType() == 6 or geom.GetGeometryType() == -2147483642: | ||
294 | - for i in range(geom.GetGeometryCount()): | ||
295 | - polygons.append(geom.GetGeometryRef(i)) | ||
296 | - del ds | ||
297 | - zh = Zonghe("d") | ||
298 | - pre = zh.get_polygon_reprecent_point(polygons[0]) | ||
299 | - print(pre) | ||
300 | - | ||
301 | - result="J:\Data\矢量数据\佛山\制图综合\zhresult.shp" | ||
302 | - print(pre) | ||
303 | - | ||
304 | - ShapeUtil.create_point(result,"zh",pre) | 500 | + create = True |
501 | + create = False | ||
502 | + | ||
503 | + if create: | ||
504 | + | ||
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]) | ||
522 | + | ||
523 | + | ||
524 | + | ||
525 | + zh.create_delauney_test() | ||
526 | + | ||
527 | + | ||
528 | + else: | ||
529 | + | ||
530 | + | ||
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" | ||
538 | + ShapeUtil.create_shp_fromwkts(result,"zh",wkts) | ||
305 | 539 |
请
注册
或
登录
后发表评论