Advertisement
Dorijanko

Program za računanje udaljenosti županija od mora

Jun 3rd, 2025
405
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.94 KB | None | 0 0
  1. import shapefile
  2. import matplotlib.pyplot as plt
  3. import math
  4. import pycrs
  5. import pyproj
  6. import sys
  7. def toCartesian(p):
  8.     degToRad=math.pi/180
  9.     return (math.cos(p[1]*degToRad)*math.cos(p[0]*degToRad),math.cos(p[1]*degToRad)*math.sin(p[0]*degToRad),math.sin(p[1]*degToRad))
  10. def fromCartesian(p):
  11.     degToRad=math.pi/180
  12.     return (math.atan2(p[1],p[0])/degToRad,math.asin(p[2])/degToRad)
  13. def normalize(p):
  14.     dis=math.sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2])
  15.     return (p[0]/dis,p[1]/dis,p[2]/dis)
  16. def cross(a,b):
  17.     return (a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0])
  18. def dist(a,b):
  19.     lat1=a[1]
  20.     lat2=b[1]
  21.     lon1=a[0]
  22.     lon2=b[0]
  23.     p=math.pi/180
  24.     a=0.5 - math.cos((lat2-lat1)*p)/2 + math.cos(lat1*p) * math.cos(lat2*p) * (1-math.cos((lon2-lon1)*p))/2 # https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula
  25.     return 2*math.asin(math.sqrt(a))
  26. def nearPointGreatCircle(a,b,c): # https://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point-to-a-line-segment-on-a-sphere
  27.     a1,b1,c1=map(toCartesian,(a,b,c))
  28.     G=cross(a1,b1)
  29.     F=cross(c1,G)
  30.     t=normalize(cross(G,F))
  31.     return fromCartesian(t)
  32. def onSegment(a,b,c):
  33.     return abs(dist(a,b)-dist(a,c)-dist(c,b))<10**-9
  34. def segDist(a,b,c):
  35.     t=nearPointGreatCircle(a,b,c)
  36.     if onSegment(a,b,t):
  37.         return dist(c,t)
  38.     return min(dist(c,a),dist(c,b))
  39. koordGrad=open('koordList.txt','rb').read().split(b'\n')
  40. stanov={}
  41. zupGrada={}
  42. popis=open('popis2011.txt','rb').read().split(b'\n') # uzimamo koji je grad u kojoj županiji iz popisa stanovništva; prvo smo tražili težinsku udaljenost gdje je težina svakog grada/općine bio njezin broj stanovnika, ali budući da je bilo čudno da se udaljenost od mora mijenja kroz vrijeme na kraju nismo koristili broj stanovnika
  43. for x in popis:
  44.     z=x.split(b'\t')
  45.     if z[1]==b'':
  46.         continue
  47.     if z[4][:5]!=b'Vinod':
  48.         imeGrada=z[1]+b' '+z[4]
  49.     else:
  50.         imeGrada=z[4]
  51.     if ' – '.encode() in imeGrada:
  52.         imeGrada=imeGrada.split(' – '.encode())[0]
  53.     stan=int(b''.join(z[-1].split(b',')))
  54.     stanov[imeGrada]=stan
  55.     zupGrada[imeGrada]=z[0]
  56. for x in koordGrad:
  57.     z=x.split(b'\t')
  58.     imeGrada=z[2].split(b'\r')[0]
  59.     xCoord=float(z[1])
  60.     yCoord=float(z[0])
  61.     zup=zupGrada[imeGrada]
  62.     pop=stanov[imeGrada]
  63. sf=shapefile.Reader('eea_v_3035_100_k_coastline-poly_1995-2017_p_v03_r00.zip')
  64. fromcrs=pycrs.load.from_file("eea_v_3035_100_k_coastline-poly_1995-2017_p_v03_r00/EEA_Coastline_20170228.prj")
  65. fromproj=pyproj.crs.CRS.from_wkt(fromcrs.to_ogc_wkt())
  66. tocrs=pycrs.parse.from_epsg_code(4326)
  67. toproj=pyproj.crs.CRS.from_wkt(tocrs.to_ogc_wkt())
  68. transformer=pyproj.Transformer.from_crs(fromproj,toproj)
  69. print(sf)
  70. fig,ax=plt.subplots()
  71. hrv_obala=sf.shape(33540).points[328000:350000] # dio obale koji je relevantan za hrvatsku
  72. minx=min([hrv_obala[i][0] for i in range(len(hrv_obala))])
  73. maxx=max([hrv_obala[i][0] for i in range(len(hrv_obala))])
  74. miny=min([hrv_obala[i][1] for i in range(len(hrv_obala))])
  75. maxy=max([hrv_obala[i][1] for i in range(len(hrv_obala))])
  76. for i in range(len(hrv_obala)):
  77.     hrv_obala[i]=transformer.transform(hrv_obala[i][0],hrv_obala[i][1]) # pretvorimo projekciju koja se koristila u koordinate
  78. xs=[p[0] for p in hrv_obala]
  79. ys=[p[1] for p in hrv_obala]
  80. ax.plot(xs,ys)
  81. otoci=[]
  82. for i in range(70972):
  83.     boundingBox=sf.shape(i).bbox
  84.     if boundingBox[0]>minx and boundingBox[1]>miny and boundingBox[2]<maxx and boundingBox[3]<maxy: # ako je otok potpuno sadržan u bounding boxu hrvatske obale onda je to hrvatski otok kojeg također treba gledati
  85.         otok=[]
  86.         for x in sf.shape(i).points:
  87.             otok.append(transformer.transform(x[0],x[1]))
  88.         xs=[p[0] for p in otok]
  89.         ys=[p[1] for p in otok]
  90.         ax.plot(xs,ys)
  91.         otoci.append(otok)
  92. plt.show()
  93. totStanovnika={}
  94. zbrUdalj={}
  95. zupanije=[]
  96. for x in koordGrad:
  97.     z=x.split(b'\t')
  98.     imeGrada=z[2].split(b'\r')[0]
  99.     xCoord=float(z[1])
  100.     yCoord=float(z[0])
  101.     zup=zupGrada[imeGrada]
  102.     pop=stanov[imeGrada]
  103.     pop=1
  104.     toc=(xCoord,yCoord)
  105.     minDist=-1
  106.     for i in range(len(hrv_obala)-1):
  107.         di=segDist(hrv_obala[i],hrv_obala[i+1],toc)
  108.         if minDist==-1 or di<minDist:
  109.             minDist=di
  110.     for obala_otoka in otoci:
  111.         for i in range(len(obala_otoka)-1):
  112.             di=segDist(obala_otoka[i],obala_otoka[i+1],toc)
  113.         if minDist==-1 or di<minDist:
  114.             minDist=di
  115.     minDist*=6371 # radijus zemlje u km
  116.     print(imeGrada,xCoord,yCoord,zup,pop,minDist)
  117.     if zup not in zupanije:
  118.         zupanije.append(zup)
  119.         totStanovnika[zup]=0
  120.         zbrUdalj[zup]=0
  121.     totStanovnika[zup]+=pop
  122.     zbrUdalj[zup]+=pop*minDist
  123. ff=open('res.txt','wb')
  124. for x in zupanije:
  125.     prosUdalj=zbrUdalj[x]/totStanovnika[x]
  126.     print(x,prosUdalj,totStanovnika[x])
  127.     ff.write(x+b': '+str(prosUdalj).encode()+b'\n')
  128. ff.close()
  129.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement