JSON是通过键值对表示数据对象的一种格式,其全称为JavaScript Object Notation,它采用完全独立于编程语言的文本格式来存储和表示数据,轻量级、简洁清晰的层次结构、容易解析等特点使得JSON 成为理想的数据交换语言。它易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率,正不断成为一种越来越受欢迎的数据格式。GeoJson一种基于Json并对各种地理数据结构进行编码的格式,它将所有的地理要素分为Point、MultiPoint、LineString、MultiLineString、LinearRing、Polygon和MultiPolygon,每个完整的GeoJson数据结构总是一个完整的地理对象,比如一个GeoJson对象示例如下图所示:
在最近的项目中,需要用到GeoJson格式的面状数据来裁剪Tiff影像,刚开始的时候曾尝试使用Java来直接写,但是用了JAI库和GDAL库,都没有找到带有空间参考的多边形来裁剪Tiff影像的接口,无奈只能用Python来完成这一功能,不得不感叹Python语言的简洁美,使用Rasterio这个库可以完美实现这一功能,并且代码量非常之少。
本程序使用Python3.7版本,需要用到GDAL库和Rasterio库,可以在此链接中下载对应版本并安装:https://www.lfd.uci.edu/~gohlke/pythonlibs/
先放上整个过程使用的Python代码:
1 # -*- coding: utf-8 -*- 2 import rasterio 3 import json 4 from rasterio.mask import mask 5 6 def Clip(Tiff, Geodata): 7 rasterfile = Tiff 8 geoms = json.loads(Geodata) # 解析string格式的geojson数据 9 rasterdata = rasterio.open(rasterfile) 10 member = 0.0 # 记录总人数 11 Gridnumber = 0 # 记录相交区域总像素点数 12 Transform = rasterdata._transform # 得到影像六参数 13 14 for i in range(len(geoms['features'])): 15 geo = [geoms['features'][i]['geometry']] 16 # 掩模得到相交区域 17 out_image, out_transform = mask(rasterdata, geo, all_touched=True, crop=True, nodata=rasterdata.nodata) 18 out_list = out_image.tolist() 19 out_list = out_list[0] 20 21 for k in range(len(out_list)): 22 for j in range(len(out_list[k])): 23 if out_list[k][j] >= 0: 24 member += out_list[k][j] 25 Gridnumber += 1 26 27 # 人数单位为万人,小数点后保留两位 28 print(round(member / 2500, 2)) 29 # 面积单位为平方公里,小数点后保留两位 30 print(round(Gridnumber * Transform[0] * Transform[3] / 250000, 2)) 31 32 if __name__ == '__main__': 33 geojson = "{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[114.4,21.2],[118.25777710514137,21.2],[118.25890798273747,21.299120898984143],[118.25711853337589,21.398166452889882],[118.25240412231551,21.49706137436084],[118.24476226308434,21.59573049143711],[118.23419263830453,21.694098805135695],[118.22069711944573,21.792091546888855],[118.20427978543194,21.88963423579395],[118.1849469400189,21.98665273562841],[118.16270712785808,22.08307331158244],[118.13757114915893,22.178822686664432],[118.10955207286088,22.27382809773303],[118.07866524822043,22.368017351110097],[118.04492831472203,22.461318877731173],[118.00836121021473,22.553661787787973],[117.96898617717864,22.644975924820585],[117.926827767026,22.735191919215197],[117.88191284233778,22.82424124106683],[117.83427057694053,22.912056252364096],[117.78393245372968,22.998570258456652],[117.73093226014316,23.083717558764647],[117.67530608119807,23.1674334966915],[117.6170922900003,23.24965450870252],[117.55633153564213,23.330318172531292],[117.49306672840999,23.409363254478194],[117.42734302222539,23.48672975576602],[117.35920779424919,23.562358957917922],[117.28871062158521,23.636193467125167],[117.21590325502609,23.708177257571663],[117.1408395897904,23.77825571368504],[117.06357563320853,23.846375671283738],[116.98416946932252,23.912485457590833],[116.90268122037355,23.97653493008744],[116.81917300516056,24.038475514178003],[116.73370889426224,24.09826023964223],[116.64635486212364,24.155843775848723],[116.55717873602077,24.211182465706713],[116.46625014192614,24.264234358333454],[116.373640447306,24.314959240415533],[116.27942270089693,24.36331866624397],[116.18367156951217,24.409275986403543],[116.08646327194742,24.45279637509782],[115.98787551005853,24.49384685609334],[115.88798739710091,24.53239632726536],[115.78687938342739,24.56841558373185],[115.68463317965143,24.601877339558882],[115.58133167739447,24.632756248027192],[115.47705886774554,24.661028920444664],[115.37189975756928,24.686673943495634],[115.26594028380782,24.70967189511566],[115.15926722593179,24.73000535888241],[115.05196811670135,24.747658936914036],[114.94413115140696,24.762619261268355],[114.83584509576394,24.774875003835064],[114.72719919264455,24.784416884715597],[114.6182830678307,24.791237679086407],[114.50918663498032,24.795332222540992],[114.40000000000009,24.796697414907612],[114.4,21.2]]]},"properties":null},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[114.4,21.2],[114.40000000000009,18.50228308467689],[114.47839318760532,18.503307199671838],[114.55672962365122,18.506378768250386],[114.63495259319666,18.511495461774075],[114.71300545451652,18.518653401114477],[114.79083167565796,18.52784715955488],[114.8683748709343,18.53906976685056],[114.9455788373358,18.552312714444042],[115.022387590839,18.567565961832713],[115.09874540259307,18.58481794408408],[115.17459683496372,18.60405558049382],[115.24988677741851,18.62526428438133],[115.32456048223082,18.648427974015192],[115.39856359998942,18.673529084662846],[115.47184221489294,18.7005485817549],[115.54434287981474,18.729465975156472],[115.61601265112176,18.760259334534908],[115.68679912323262,18.79290530581477],[115.75665046289964,18.827379128707662],[115.82551544320313,18.863654655305822],[115.89334347724332,18.901704369726474],[115.96008465151897,18.94149940879379],[116.0256897589802,18.983009583743524],[116.09011033174647,19.02620340293629],[116.15329867347828,19.07104809556239],[116.21520789139402,19.11750963632312],[116.27579192792268,19.165552771070054],[116.33500559198546,19.215141043384506],[116.3928045898956,19.266236822078668],[116.44914555587411,19.318801329598273],[116.5039860821679,19.37279467130668],[116.55728474876958,19.428175865629328],[116.6090011527283,19.484902875036482],[116.65909593704691,19.54293263784183],[116.70753081915825,19.602221100793372],[116.75426861897427,19.662723252433352],[116.79927328650058,19.724393157201348],[116.84250992900877,19.78718399025621],[116.88394483776051,19.851048072990466],[116.92354551427263,19.915936909210018],[116.96128069611666,19.981801221953162],[116.99712038224084,20.04859099091908],[117.03103585780605,20.11625549047926],[117.06299971852206,20.184743328241552],[117.09298589447349,20.254002484137857],[117.12096967341938,20.323980350004945],[117.14692772355352,20.394623769628254],[117.17083811570683,20.465879079217302],[117.19268034497554,20.53769214828128],[117.21243535175506,20.610008420873214],[117.23008554215835,20.682772957169675],[117.24561480779653,20.755930475354717],[117.25900854489805,20.829425393773647],[117.27025367273882,20.903201873324804],[117.27933865135765,20.977203860054487],[117.2862534985261,21.051375127922938],[117.29098980594381,21.125659321706053],[117.29354075462402,21.19999999999999],[114.4,21.2]]]},"properties":null},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[114.4,21.2],[111.50645924537594,21.19999999999999],[111.50901019405615,21.125659321706053],[111.51374650147397,21.051375127922938],[111.52066134864242,20.977203860054487],[111.52974632726114,20.903201873324804],[111.5409914551019,20.829425393773647],[111.55438519220343,20.755930475354717],[111.56991445784172,20.682772957169675],[111.587564648245,20.610008420873214],[111.60731965502441,20.53769214828128],[111.62916188429313,20.465879079217302],[111.65307227644644,20.394623769628254],[111.67903032658069,20.323980350004945],[111.70701410552658,20.254002484137857],[111.737000281478,20.184743328241552],[111.76896414219402,20.11625549047926],[111.80287961775912,20.04859099091908],[111.83871930388341,19.981801221953162],[111.87645448572744,19.915936909210018],[111.91605516223956,19.851048072990466],[111.9574900709913,19.787183990256267],[112.00072671349949,19.724393157201348],[112.04573138102569,19.662723252433352],[112.09246918084182,19.602221100793372],[112.14090406295315,19.54293263784183],[112.19099884727166,19.484902875036482],[112.24271525123038,19.428175865629328],[112.29601391783206,19.37279467130668],[112.35085444412584,19.318801329598273],[112.40719541010435,19.266236822078668],[112.46499440801472,19.215141043384506],[112.52420807207727,19.165552771070054],[112.58479210860605,19.11750963632312],[112.64670132652168,19.07104809556239],[112.70988966825348,19.02620340293629],[112.77431024101975,18.983009583743524],[112.83991534848099,18.94149940879379],[112.90665652275675,18.901704369726474],[112.97448455679694,18.863654655305822],[113.04334953710043,18.827379128707662],[113.11320087676745,18.79290530581477],[113.18398734887819,18.760259334534908],[113.25565712018533,18.729465975156472],[113.32815778510712,18.7005485817549],[113.40143640001065,18.673529084662846],[113.47543951776925,18.648427974015192],[113.55011322258156,18.62526428438133],[113.62540316503623,18.60405558049382],[113.701254597407,18.58481794408408],[113.77761240916095,18.567565961832713],[113.85442116266427,18.552312714444042],[113.93162512906565,18.53906976685056],[114.009168324342,18.52784715955488],[114.08699454548355,18.518653401114477],[114.16504740680341,18.511495461774075],[114.24327037634885,18.506378768250386],[114.32160681239475,18.503307199671838],[114.40000000000009,18.50228308467689],[114.4,21.2]]]},"properties":null},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[114.4,21.2],[114.40000000000009,23.448160895495334],[114.33247352966828,23.447307394069753],[114.26500097353119,23.444747537182025],[114.19763619552975,23.44048326651341],[114.13043295917385,23.434517816577568],[114.06344487751585,23.42685571229009],[113.99672536335152,23.41750276556752],[113.93032757972082,23.406466070958686],[113.86430439078458,23.39375400031156],[113.7987083131469,23.379376196479143],[113.7335914676953,23.363343566068465],[113.66900553202856,23.345668271238367],[113.60500169353759,23.326363720550944],[113.54163060320673,23.30544455888355],[113.47894233019758,23.282926656408677],[113.41698631727627,23.258827096647906],[113.35581133714209,23.23316416361058],[113.29546544971413,23.205957328023942],[113.23599596042686,23.177227232665985],[113.17744937958537,23.14699567681066],[113.11987138282689,23.115285599796152],[113.0633067727324,23.08212106372895],[113.0077994416265,23.047527235334712],[112.95339233560537,23.011530366969794],[112.90012741982423,22.97415777680635],[112.84804564507613,22.93543782820609],[112.79718691568678,22.895399908296383],[112.74759005875148,22.854074405765346],[112.69929279473217,22.81149268789119],[112.65233170943259,22.76768707682311],[112.60674222736463,22.722690825130428],[112.56255858651605,22.676538090638587],[112.51981381452674,22.629263910570103],[112.47853970627853,22.58090417500955],[112.43876680289759,22.531495599712457],[112.40052437217025,22.481075698278232],[112.36384039036511,22.429682753707652],[112.32874152545742,22.377355789366675],[112.29525312174269,22.32413453937818],[112.26339918583005,22.270059418463347],[112.23320237400071,22.21517149125674],[112.20468398091452,22.15951244111716],[112.17786392964763,22.103124538458587],[112.15276076304008,22.046050608625364],[112.12939163633348,21.988333999335737],[112.10777231107431,21.93001854771967],[112.08791715026041,21.87114854697478],[112.0698391147032,21.8117687126678],[112.05354976058175,21.75192414870628],[112.03905923816069,21.69166031300722],[112.02637629164292,21.631022982889874],[112.01550826013147,21.570058220218527],[112.00646107967054,21.508812336323217],[111.99923928633655,21.447331856725555],[111.99384602035161,21.38566348569634],[111.99028303118871,21.323854070674486],[111.98855068364242,21.26195056657275],[111.98864796483326,21.19999999999999],[114.4,21.2]]]},"properties":null}]}" 34 ClipImage.Clip("E:WorkspacesGuangDongRe.tif",geojson)
传入的参数是string格式的Geojson数据,需要用json.loads()函数来解析,注意必须是标准格式的Geojson,任何一个符号都不能缺少,否则会导致无法解析。
经过调试发现,rasterio.mask()函数对传入的用来裁剪的边界数据要求也很高,必须是转化为list形式的Geojson,示例如下:
[{'type': 'Polygon', 'coordinates': [[[114.4, 21.2], [118.25777710514137, 21.2], [118.25890798273747, 21.299120898984143], [118.25711853337589, 21.398166452889882], [118.25240412231551, 21.49706137436084], [118.24476226308434, 21.59573049143711], [118.23419263830453, 21.694098805135695], [118.22069711944573, 21.792091546888855], [118.20427978543194, 21.88963423579395], [118.1849469400189, 21.98665273562841], [118.16270712785808, 22.08307331158244], [118.13757114915893, 22.178822686664432], [118.10955207286088, 22.27382809773303], [118.07866524822043, 22.368017351110097], [118.04492831472203, 22.461318877731173], [118.00836121021473, 22.553661787787973], [117.96898617717864, 22.644975924820585], [117.926827767026, 22.735191919215197], [117.88191284233778, 22.82424124106683], [117.83427057694053, 22.912056252364096], [117.78393245372968, 22.998570258456652], [117.73093226014316, 23.083717558764647], [117.67530608119807, 23.1674334966915], [117.6170922900003, 23.24965450870252], [117.55633153564213, 23.330318172531292], [117.49306672840999, 23.409363254478194], [117.42734302222539, 23.48672975576602], [117.35920779424919, 23.562358957917922], [117.28871062158521, 23.636193467125167], [117.21590325502609, 23.708177257571663], [117.1408395897904, 23.77825571368504], [117.06357563320853, 23.846375671283738], [116.98416946932252, 23.912485457590833], [116.90268122037355, 23.97653493008744], [116.81917300516056, 24.038475514178003], [116.73370889426224, 24.09826023964223], [116.64635486212364, 24.155843775848723], [116.55717873602077, 24.211182465706713], [116.46625014192614, 24.264234358333454], [116.373640447306, 24.314959240415533], [116.27942270089693, 24.36331866624397], [116.18367156951217, 24.409275986403543], [116.08646327194742, 24.45279637509782], [115.98787551005853, 24.49384685609334], [115.88798739710091, 24.53239632726536], [115.78687938342739, 24.56841558373185], [115.68463317965143, 24.601877339558882], [115.58133167739447, 24.632756248027192], [115.47705886774554, 24.661028920444664], [115.37189975756928, 24.686673943495634], [115.26594028380782, 24.70967189511566], [115.15926722593179, 24.73000535888241], [115.05196811670135, 24.747658936914036], [114.94413115140696, 24.762619261268355], [114.83584509576394, 24.774875003835064], [114.72719919264455, 24.784416884715597], [114.6182830678307, 24.791237679086407], [114.50918663498032, 24.795332222540992], [114.40000000000009, 24.796697414907612], [114.4, 21.2]]]}]
传入的Geojson数据不需要设计空间参考,程序会自动将其设置为Tiff影像的空间参考,裁剪得到的部分影像都存储在out_image变量中,out_list = out_image.tolist()可以直接读取像素值为list,接下来如何计算就各取所需了。
本程序最后的运行结果如下图所示: