提交 f54eb3c010c2e764ee363d46bb390eac2c134395

作者 nheweijun
1 个父辈 7cfdffa1

2022.03.11 合并备份

... ... @@ -17,7 +17,7 @@ from app.util.component.StructurePrint import StructurePrint
17 17 from app.util.component.PGUtil import PGUtil
18 18 import os
19 19 from app.modules.monitor.schedule import start_schedule
20   -import requests
  20 +import platform
21 21
22 22 class JSONEncoder(_JSONEncoder):
23 23 """
... ... @@ -128,7 +128,7 @@ def create_app():
128 128
129 129 # 不检测https
130 130 os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
131   -
132   - start_schedule()
  131 + if platform.system().lower() == "linux":
  132 + start_schedule()
133 133 return app
134 134
... ...
... ... @@ -13,7 +13,7 @@ import time
13 13 from app.models import SM3, AESHelper
14 14 from app.util.component.StructurePrint import StructurePrint
15 15 import traceback
16   -from oauthlib import oauth2
  16 +# from oauthlib import oauth2
17 17 import requests
18 18 from app.modules.auth.models import OAuth2Token, User, db
19 19
... ...
... ... @@ -37,7 +37,7 @@ class Api(ApiTemplate):
37 37 download_process.start()
38 38
39 39 task = Task(guid=task_guid,
40   - name="下载|{}".format(self.para.get("table_name")),
  40 + name="下载 | {}".format(self.para.get("table_name")),
41 41 create_time=datetime.datetime.now(),
42 42 state=0,
43 43 task_type=4,
... ...
... ... @@ -83,7 +83,7 @@ class Api(ApiTemplate):
83 83 # 录入数据后台进程,录入主函数为entry
84 84 # 初始化task
85 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 87 create_time=datetime.datetime.now(),
88 88 state=0,
89 89 task_type=1,
... ...
... ... @@ -323,6 +323,7 @@ class ThisTask:
323 323 this_time = datetime.datetime.now()
324 324
325 325 ext = layer.GetExtent()
  326 +
326 327 if ext[0] < 360:
327 328 ext = [round(e, 6) for e in ext]
328 329 else:
... ...
... ... @@ -23,7 +23,7 @@ class Api(ApiTemplate):
23 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 28 try:
29 29 if self.para.get("column_alias"):
... ...
... ... @@ -35,7 +35,7 @@ class Api(ApiTemplate):
35 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 40 if not database:
41 41 res["result"]=False
... ...
... ... @@ -33,7 +33,7 @@ class Api(ApiTemplate):
33 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 38 if self.para.__contains__("catalog_guid"):
39 39 if catalog_guid is None:
... ...
... ... @@ -39,7 +39,7 @@ class Api(ApiTemplate):
39 39 refresh_process.start()
40 40
41 41 task = Task(guid=task_guid,
42   - name="更新|{}".format(database.alias),
  42 + name="更新 | {}".format(database.alias),
43 43 create_time=datetime.datetime.now(),
44 44 state=0,
45 45 task_type=3,
... ... @@ -335,7 +335,7 @@ class Api(ApiTemplate):
335 335 try:
336 336 # 删除表
337 337 if table.name not in db_tables_names:
338   - StructurePrint().print("空间表减少!")
  338 + StructurePrint().print("{}空间表减少!".format(table.name))
339 339 sys_session.delete(table)
340 340 # 修改表
341 341 else:
... ...
... ... @@ -42,7 +42,7 @@ class Api(ApiTemplate):
42 42 raise Exception("数据不存在!")
43 43
44 44 #验证权限
45   - UserCheck.verify(table.relate_database.creator)
  45 + UserCheck.verify(table.creator)
46 46
47 47 pg_ds :DataSource= PGUtil.open_pg_data_source(0,DES.decode(table.relate_database.sqlalchemy_uri))
48 48 layer = pg_ds.GetLayerByName(table.name)
... ... @@ -76,7 +76,7 @@ class Api(ApiTemplate):
76 76
77 77
78 78 task = Task(guid=task_guid,
79   - name="矢量金字塔|{}".format(table.name),
  79 + name="矢量金字塔 | {}".format(table.name),
80 80 table_guid=table_guid,
81 81 create_time=datetime.datetime.now(),
82 82 state=0,
... ...
... ... @@ -42,7 +42,7 @@ class Api(ApiTemplate):
42 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 80
81 81 task = Task(guid=task_guid,
82 82 # name="矢量金字塔|{},网格大小:{}".format(table.name,self.para.get("grids")),
83   - name="矢量金字塔|{}".format(table.name),
  83 + name="矢量金字塔 | {}".format(table.name),
84 84 table_guid=table_guid,
85 85 create_time=datetime.datetime.now(),
86 86 state=0,
... ...
... ... @@ -33,7 +33,7 @@ class Api(ApiTemplate):
33 33
34 34
35 35 task = Task(guid=task_guid,
36   - name="影像金字塔|{}".format(self.para.get("alias")),
  36 + name="影像金字塔 | {}".format(self.para.get("alias")),
37 37 create_time=datetime.datetime.now(),
38 38 state=0,
39 39 task_type=5,
... ...
... ... @@ -3,13 +3,12 @@
3 3 #createtime: 2021/7/19
4 4 #email: nheweijun@sina.com
5 5
6   -
7 6 from app.util.component.ApiTemplate import ApiTemplate
8   -from .models import TileService,db,Service,MapService
9 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 9 from .util.ServiceType import ServiceType
  10 +from .util.TileProjectFile import ProjectFile
  11 +
13 12 class Api(ApiTemplate):
14 13
15 14 api_name = "服务reload"
... ...
... ... @@ -5,9 +5,7 @@
5 5
6 6
7 7 from app.util.component.ApiTemplate import ApiTemplate
8   -from app.util.component.ModelVisitor import ModelVisitor
9 8 from app.util.component.FileProcess import FileProcess
10   -from .models import Service
11 9 import os
12 10
13 11 class Api(ApiTemplate):
... ...
... ... @@ -3,12 +3,12 @@
3 3 #createtime: 2021/9/14
4 4 #email: nheweijun@sina.com
5 5
  6 +import requests
  7 +import configure
6 8 from app.util.component.UserCheck import UserCheck
7 9 from app.util.component.ApiTemplate import ApiTemplate
8 10 from .models import Service,db
9   -import requests
10 11 from .util.ServiceType import ServiceType
11   -import configure
12 12
13 13 class Api(ApiTemplate):
14 14 api_name = "修改服务状态"
... ... @@ -26,20 +26,20 @@ class Api(ApiTemplate):
26 26
27 27 if service:
28 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 43 res["result"] = True
44 44 else:
45 45 raise Exception("服务不存在!")
... ...
... ... @@ -10,7 +10,7 @@ import uuid
10 10 from ..models import TileService,Service,db,ServiceFunction,TileScheme
11 11 import datetime
12 12 import requests
13   -from .util.ProjectFile import ProjectFile
  13 +from ..util.TileProjectFile import ProjectFile
14 14 import json
15 15 from requests import Response
16 16 import configure
... ...
... ... @@ -14,7 +14,7 @@ import configure
14 14 import requests
15 15 from requests import Response
16 16 import json
17   -from .util.ProjectFile import ProjectFile
  17 +from ..util.TileProjectFile import ProjectFile
18 18
19 19 class Api(ApiTemplate):
20 20
... ...
... ... @@ -9,7 +9,7 @@ from ..models import TileService,db,Service,MapService
9 9 import configure
10 10 from app.util.component.ModelVisitor import ModelVisitor
11 11
12   -from .util.ProjectFile import ProjectFile
  12 +from ..util.TileProjectFile import ProjectFile
13 13 from ..util.ServiceType import ServiceType
14 14
15 15 class Api(ApiTemplate):
... ...
... ... @@ -6,10 +6,6 @@
6 6
7 7 from app.util.component.ApiTemplate import ApiTemplate
8 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 9 from flask import request
14 10 import uuid
15 11 import configure
... ...
... ... @@ -92,21 +92,28 @@ class GeometryAdapter:
92 92 # PolyhedralSurface = 15,
93 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 103 # MultiPointZ = -2147483644
96 104 # MultiLineStringZ = -2147483643
97 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 113 return 1
107   - elif raw == -2147483643 or raw == -2147483646:
  114 + elif raw in [2, 5, -2147483643, -2147483646, 3002, 3005]:
108 115 return 2
109   - elif raw == -2147483642 or raw == -2147483645:
  116 + elif raw in [3, 6, -2147483642, -2147483645, 3003, 3006] :
110 117 return 3
111 118 return raw
112 119
... ...
... ... @@ -34,7 +34,7 @@ class SQLUtil:
34 34 :return:
35 35 '''
36 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 38 .format(user,table_name,pri_type)).fetchall()
39 39 if len(pri) == 1:
40 40 return True
... ...
... ... @@ -9,10 +9,14 @@ import shutil
9 9
10 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 17 if os.path.exists(des):
13 18 os.system("rd/s/q {}".format(des))
14 19 shutil.rmtree(des, True)
15   - project_dir = os.path.dirname(os.path.realpath(__file__))
16 20
17 21 shutil.copytree(project_dir, des)
18 22 git_path = os.path.join(des,".git")
... ...
... ... @@ -353,6 +353,19 @@ AddDefaultCharset UTF-8
353 353 #EnableMMAP off
354 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 369 # Supplemental configuration
357 370 #
358 371 # Load config files in the "/etc/httpd/conf.d" directory, if any.
... ...
... ... @@ -22,88 +22,20 @@ from osgeo.ogr import *
22 22 import base64
23 23
24 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 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()
\ No newline at end of file
  41 + print(layer.GetGeomType())
\ No newline at end of file
... ...
... ... @@ -2,3 +2,304 @@
2 2 #author: 4N
3 3 #createtime: 2022/3/8
4 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 54 layer.CreateFeature(feat_new)
55 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 87 class ShapeData:
59 88
... ... @@ -85,7 +114,7 @@ class ShapeData:
85 114 class Zonghe:
86 115
87 116 data:ShapeData
88   - area_threshold = 10.0
  117 + area_threshold = 20.0
89 118 buffer_threshold = 100.0
90 119
91 120 def __init__(self,data):
... ... @@ -96,174 +125,363 @@ class Zonghe:
96 125 #只处理Polygon,MultiPolygon要拆开
97 126 def get_polygon_reprecent_point(self,polygon:Geometry):
98 127
99   - polygon_area = polygon.GetArea()
100   -
101 128 polygon_env = polygon.GetEnvelope()
102 129
103 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 135 center:Geometry = polygon.Centroid()
  136 +
  137 + # 提前return
106 138 if polygon.Contains(center):
107 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 150 if polygon.GetGeometryCount() == 1:
117 151 polygon_line = ogr.ForceToLineString(polygon)
118   - # 有孔Polygon
  152 +
  153 + # 有孔Polygon,要分2种情况
119 154 else:
120 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 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 188 for gi in range(clip_geom.GetGeometryCount()):
168 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 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 247 point_intersection:Geometry = line.Intersection(polygon_line)
221   -
222 248 xlist = []
223 249 ylist = []
  250 + plist = []
  251 +
224 252 for i in range(point_intersection.GetGeometryCount()):
225 253 pi = point_intersection.GetGeometryRef(i)
226 254 xlist.append(pi.GetX())
227 255 ylist.append(pi.GetY())
  256 + plist.append(pi)
228 257
229 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 353 line: Geometry = ogr.Geometry(ogr.wkbLineString)
238 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 361 if x1 != x0:
242 362 y2 = ((y1-y0)*(x2-x0))/(x1-x0) + y0
243 363 else:
244 364 x2 = x0
245   - y2 = y0 + len_size
  365 + y2 = y0 + dx
246 366 line.AddPoint(x2, y2)
247 367
248 368 other_point = ogr.Geometry(ogr.wkbPoint)
249 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 486 def process(self):
269 487 polygons = self.data.get_polygons()
... ... @@ -279,27 +497,43 @@ if __name__ == '__main__':
279 497 # print(sd.get_polygons()[0])
280 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
... ...
注册登录 后发表评论