Almost!
It turns out that blue (Lanzhou city) is close to but not exact the mass center (red). I mean, if we only consider Lanzhou as a point.
An algorithmic approach
import json
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
import cv2
# be aware to fix coordinates from 内蒙古 (add an extra bracket, download it from https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json)
with open('100000_full.json', 'r') as f:
content = json.load(f)
print(content.keys())
fig, ax = plt.subplots()
for feat in content['features']:
if feat['properties']['name'] == '甘肃省':
center = feat['properties']['center']
if feat['properties']['name'] not in ['']:
coordinates = feat['geometry']['coordinates']
for c in coordinates:
coord = np.array(c)
if len(coord[0].shape) == 2:
p = Polygon(coord[0], facecolor='k')
ax.add_patch(p)
else:
print(coord[0])
print(feat['properties']['name'])
ax.set_xlim([60, 140])
ax.set_ylim([0, 60])
cx, cy = center
print("center", center)
print("lim:", ax.get_xlim(), ax.get_ylim())
xmin, xmax = ax.get_xlim()
ymin, ymax = ax.get_ylim()
cx = (cx -60) * (640 / (xmax - xmin))
cy = 480 - cy * (480 / (ymax-ymin))
print("center scaled:", cx, cy)
plt.axis('off')
plt.tight_layout()
plt.savefig("china_map.png")
plt.show()
img = cv2.imread('china_map.png', 0)
print(img.shape, img.mean(), img.max(), img.min())
th, im_th = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY_INV)
print(th)
print(im_th.shape)
cv2.imwrite('china_map_inverse.png', im_th)
moments = cv2.moments(im_th, True)
print(moments)
centeroid = (moments['m10'] / moments['m00'], moments['m01'] / moments['m00'])
print("centeroid:", centeroid)
x,y = centeroid
fig,ax = plt.subplots()
img = cv2.imread('china_map.png')
ax.imshow(img)
plt.scatter(x, y, c='r')
plt.scatter(cx, cy, c='b')
plt.tight_layout()
plt.axis('off')
plt.savefig('china_map_with_centeroid.png')
plt.show()
References
- https://blog.csdn.net/qq826309057/article/details/70039397
- https://www.zhoulujun.cn/html/GIS/WebGIS/8348.html
- http://datav.aliyun.com/portal/school/atlas/area_selector#&lat=33.50475906922609&lng=104.2822265625&zoom=4