Thursday 28 March 2019

gdal - Using dictionary of file names and DD coordinates to create points in shapefile using shapely?


I'm working on a Python script that strips the GPS info from images and uses that info to create a shapefile from that info. Right now I have all the file names as keys to tuples of decimal degrees coordinates. This dictionary prints out like this:


{'IMG_2840.jpg': (39.08861111111111, 114.80472222222222), 'IMG_2823.jpg': (38.61611111111111, 119.88777777777777), 'IMG_2912.jpg': (41.97861111111111, 106.25500000000001), 'IMG_2859.jpg': (39.742777777777775, 112.19694444444444), 'IMG_2813.jpg': (39.200833333333335, 119.79416666666665), 'IMG_2790.jpg': (41.82111111111111, 121.72472222222221), 'IMG_2753.jpg': (41.72027777777778, 124.32249999999999), 'IMG_2916.jpg': (41.01388888888889, 105.97611111111111), 'IMG_2750.jpg': (42.50833333333333, 125.72888888888889)}

How would I take this dictionary and turn it into a shapefile so that the names of the files are the names of the points?


I would prefer an open source way such as shapely or ogr/gdal.


Here's the code that generated this list. It does not really deal with spatial data at all.


filelist = os.listdir(Path)

for f in filelist:
if f.endswith(".jpg"):
with open(Path + "/" + f, 'r') as I:
print(I)
img = Image.open(Path + "/" + f)
exif = {ExifTags.TAGS[k]: v for k, v in img._getexif().items() if k in ExifTags.TAGS}
print(exif)
meta = exif['GPSInfo'][2]
meta = [x[0] for x in meta]
d = meta[0]

m = meta[1]
s = meta[2]
NCDict[os.path.basename(I.name)] = dms_to_dd(d=d,m=m,s=s)
# Ncoords = {I:dms_to_dd(d=d, m=m, s=s)}
# print(Ncoords)
meta2 = exif['GPSInfo'][4]
meta2 = [b[0] for b in meta2]
d = meta2[0]
m = meta2[1]
s = meta2[2]

WCDict[os.path.basename(I.name)] = dms_to_dd(d=d,m=m,s=s)
print NCDict
print WCDict

# writing xy coords to new file
corddict=[NCDict,WCDict]
finalCoord = {}
for k in NCDict.iterkeys():
finalCoord[k] = tuple(finalCoord[k] for finalCoord in corddict)
print(finalCoord)


Answer



You don't need ArcPy here, simply use the geospatial pure Python modules as GeoPandas, Fiona, Shapely, pyshp (shapefile) or osgeo.ogr


# the resulting dictionary
dicto = {'IMG_2840.jpg': (39.08861111111111, 114.80472222222222), 'IMG_2823.jpg': (38.61611111111111, 119.88777777777777), 'IMG_2912.jpg': (41.97861111111111, 106.25500000000001), 'IMG_2859.jpg': (39.742777777777775, 112.19694444444444), 'IMG_2813.jpg': (39.200833333333335, 119.79416666666665), 'IMG_2790.jpg': (41.82111111111111, 121.72472222222221), 'IMG_2753.jpg': (41.72027777777778, 124.32249999999999), 'IMG_2916.jpg': (41.01388888888889, 105.97611111111111), 'IMG_2750.jpg': (42.50833333333333, 125.72888888888889)}

With GeoPandas


# convert to a GeoDataFrame
import geopandas as gpd
result = gpd.GeoDataFrame.from_dict(dicto, orient='index').reset_index()
# rename the columns

result.columns = ['name','x','y']
print(result.head(3))
name x y
0 IMG_2840.jpg 39.088611 114.804722
1 IMG_2823.jpg 38.616111 119.887778
2 IMG_2912.jpg 41.978611 106.255000
# create a shapely geometry column
from shapely.geometry import Point
result['geometry'] = result.apply(lambda row: Point(row.x, row.y), axis=1)
# print first row as control

print(result.head(1))
name x y geometry
0 IMG_2840.jpg 39.088611 114.804722 POINT (39.08861111111111 114.8047222222222)
result.crs = "4326"
# save resulting shapefile
result.to_file("result.shp")

With Fiona:


import fiona
from shapely.geometry import mapping

from fiona.crs import from_epsg
# define the schema of the resulting shapefile
schema={'geometry': 'Point', 'properties': {'name':'str:10'}}
# create and save the resulting shapefile
with fiona.open('result2.shp', 'w',crs=from_epsg(4326),driver='ESRI Shapefile', schema=schema) as output:
for key, value in dicto.items():
point = Point(value[0],value[1])
prop = prop = {'name':key}
output.write({'geometry':mapping(point),'properties': prop})


With pyshp (without shapely)


import shapefile
w = shapefile.Writer(shapefile.POINT)
w.field('name', 'C')
for key, value in dicto.items():
w.record(key)
w.point(value[0],value[1])
w.save("result3.shp")

enter image description here



No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...