说说浏览器端WebGIS开发可能会用到的js库,提高效率,方便融入日益强大的npm生态。不过这些库大多保留了全局库的形式,也可以在非框架中使用。其中一些可用于浏览器+NodeJS。一、相关数据格式转换与分析1.1.解析和转换WKT几何数据如果你只完成WKT和GeoJSON之间的转换,那么下面的任何一个都可以完成你的任务,只需要选择库大小最小的那个。否则,只需根据您的需要进行选择。就个人体验而言,@terraformer/wkt是一个比较平衡的库。下表比较了这些库。wkt@terraformer/wktwkt-parser-helper@syncpoint/wkxtstypeno,extrainstalltssourcecodelibrarysize16.7KB86.8KB15.1KB69.7KBpurity0dependency0dependency1dependency1dependencyrichnessparse+stringifyparse+stringifyparse+stringify很丰富,还包括WKBAPI文档,详细,详细,更新。.其实大家不需要太在意这些库的更新时间,因为WKT的规范已经发布很多年了,用起来也足够简单,主要是用起来舒服。库大小并不是真正会包含在最终页面程序中的大小,因为有些库使用了bundler,库大小包括多个文件(如不同模块样式的库文件、源程序文件等).1.2.前端直接读取GeoPackage-@ngageoint/geopackageGeoPackage是一种基于SQLite3定义的简单的单文件地理数据存储格式。文件扩展名为.gpkg,可以被QGIS和ArcGIS读取。它是开源和免费的,并且支持扩展。它类似于基于SQLite3的SpatialLite,但最大的区别是SpatialLite支持数据库的基本操作,而GeoPackage更像是一个存储仓库,不像普通的数据库。pnpmadd@ngageoint/geopackage这里是一个网站GeoPackageViewer,使用这个库直接在页面上读取GeoPackage文件中的地理数据。此外,在这个@ngageoint帐户下还有一堆更积极维护的库:@ngageoint/leaflet-geopackage-Leaflet.js的一个插件,它允许gpkg直接加载到lf映射中,其余仅适用于NodeJS(浏览器不能使用)格式转换库:@ngageoint/geopackage-geojson-js-在NodeJS端使用,在GeoJSON和GeoPackage之间转换/geopackage-pbf-js-在NodeJS端使用,将pbf数据转换为GeoPackage@ngageoint/geopackage-mbtiles-js-在NodeJS端使用,将mbtiles数据转换为GeoPackage@ngageoint/geopackage-csv-js-在NodeJS端使用,将csv数据转换为GeoPackage@ngageoint/geopackage-shapefile-js-在NodeJS端使用,转换shapefilezip文件到GeoPackage1.3。前端直接读取EsriShapefile——ts-shapefileShapefile是Esri的杰作,是一种多文件数据格式,虽然我在各种场合不遗余力地推荐大家使用新的数据格式,但总有一些还在问前端能不能解析Shapefile的人。这个库的源代码是用TypeScript写的,打包后支持类型提示(withd.ts)。浏览器的捆绑库文件大约100+KB,这是可以接受的。pnpmaddts-shapefile库的使用方法见github仓库的README。注意Shapefile规范本体不包含坐标系,所以本库不解析.prj文件中的坐标系信息。坐标系的操作库见本文第二节。Mapbox团队有一个用于编写Shapefile并下载为zip供参考的库(纯js,在浏览器中可用):shp-write注意npm上的一些shapefile库是NodeJS后端库,在浏览器中不可用,例如shp2json、shp-write-stream、shp-stream等1.4.把GDAL搬进浏览器——gdal3.jsGIS开发圈GDAL可谓是大师级的库,它提供各种空间数据格式的驱动(解析器),集成了一些简单的算法实现。与npm上的gdal库不同,gdal库是NodeJS对GDAL的接口绑定。它是一个后端库,在浏览器中不可用。(p.s,gdal-async解决了gdal库的非异步问题,但是浏览器还是不能使用)。这个gdal3.js使用emscripten将GDAL转换为WebAssembly,让浏览器可以使用GDAL,但是性能上还是和绑定版本不一样。这个库的源代码是用TypeScript编写的。由于pnpmaddgdal3.js支持多种格式,它携带的WebAssembly文件多了一点,这个库的体积也扩大到了38.4MB。如果你真的想在浏览器中使用它,请慎重考虑。文档非常详细。因为它携带了wasm等附加文件,所以在打包环境中使用时也要注意复制文件。在Webpack和Vite环境中通知浏览器应用程序如何做是很时髦的。1.5.格式库总结我在很多场合说过:浏览器+JavaScript不应该用于重数据转换,所以大部分重量级的格式转换应该由后端程序完成,其他语言(runtime)有更好的实现,例如C++、Java、C#.NET、Rustlang、NodeJS、Python。有时在浏览器端是不可能做到的。它仍然能够处理一些简单的格式转换。2.操纵空间坐标系2.1.Reprojectionproj4JavaScript版著名的C++投影库PROJ,ts类型需要额外安装@types/proj4。pnpmaddproj4库只支持单个坐标的转换。对于复杂的数据格式投影转换,需要更高层次的封装库,见下文。2.2.修正“火星”和“百度”的加密坐标pnpmaddgcoord是国人为了解决“火星”和“百度”等加密算法的问题而开发的。它们在市场上通常被称为“火星坐标系”和“百度坐标系”,但实际上它们只是一些非公开的加密算法。本库可以通过拟合的方式更准确的修正加密后的坐标。它的官方文档指出它支持坐标数组和GeoJSON的转换。2.3.空间坐标系的WKT定义-spatialreference库不是用于数据坐标系转换,而是基于WKID的坐标系的WKT定义。它没有ts定义,很遗憾。其默认查询方式需要联网,通过epsg.io在线API请求查询,因此在大陆环境下可能会受到影响。pnpmaddspatialreference用法示例:importSRfrom'spatialreference'newSR({}).wkidToWkt(4326,(err,wkt)=>{if(!err)console.log(wkt)})此库还支持添加数据库端数据到输入对象,参考其文档,允许从数据库获取WKT。2.4.空间坐标系的PROJ定义-epsg如果没有在线环境,不能使用2.3库,可以使用epsg库获取坐标系的PROJ4定义。这个库带有一个JSON字典。pnpm添加epsg示例:从'epsg'console.log(epsg['EPSG:3857'])//+proj=merc+a=6378137+b=6378137+lat_ts=0.0+lon_0=0.0+x_0=0.0导入epsg+y_0=0+k=1.0+units=m+nadgrids=@null+wktext+no_defs这个库是一个commonjs模块,需要bundle转换。2.5.从坐标系定义字符串中导出WKID-get-epsg-code这是与2.3和2.4相反的操作。pnpm添加get-epsg-code示例:从'get-epsg-code'constproj4string=`+proj=merc+a=6378137+b=6378137+lat_ts=0.0+lon_0=0.0+x_0=0.0+y_0=导入getEPSGCode0+k=1.0+units=m+nadgrids=@null+wktext+no_defs`constwkid=getEPSGCode(proj4string)//3857它的文档说支持几乎所有的格式,WKT,proj4,esriproj都可以试试:在线测试。2.6.GeoJSON的重投影——reproj-helper,reproject前者是用TypeScript写的。dist/下的打包结果文件中,打包了proj4,所以体积会稍微大一些(因为proj4本身就有900+KB),优点是API和文档比较齐全,还有类型提示,但缺点是没有GeoJSON的usage定义,而是粗暴的设置为any。pnpm添加reproj-helper示例:从'reproj-helper'constpointFeature={"type":"Feature","properties":{},"geometry":{"coordinates":[27.896140109578766,20.219492193232625],"type":"Point"}}constrp=newRH.ReProjector()rp.from('4326')rp.to('3857')rp.feature(pointFeature)constresult=awaitrp.project()LaterIt比较轻巧。npmjs.com上发布的包不包含打包结果,但安装依赖时也会安装proj4,重点关注GeoJSON对象的转换,支持检查GeoJSON是否有坐标系定义。没有ts类型提示:pnpmaddreproject示例:import{reproject}from'reproject'constpointFeature={"type":"Feature","properties":{},"geometry":{"coordinates":[27.896140109578766,20.219492193232625],"type":"Point"}}console.log(reproject(pointFeature,'+proj=longlat+datum=WGS84+no_defs+type=crs','+proj=merc+a=6378137+b=6378137+lat_ts=0+lon_0=0+x_0=0+y_0=0+k=1+units=m+nadgrids=@null+wktext+no_defs+type=crs'))3.简单的空间分析和几何操作3.1.JTS的移植——jstsJTS有一个C++子GEOS,然后是一个JavaScript子jsts。JTS是一个用Java编写的几何库,其地位不言而喻。pnpmaddjstspnpmadd@types/jsts-D之前写过一篇文章如何使用,以缓冲区分析为例:importJSTSWKTReaderfrom'jsts/org/locationtech/jts/io/WKTReader'importJSTSGeoJSONWriterfrom'jsts/org/locationtech/jts/io/GeoJSONWriter'从'jsts/org/locationtech/jts/operation/buffer/BufferOp'导入JSTSBufferOpconstwkt=`POINT(00)`constbufferCenter=newJSTSWKTReader().read(wkt)constbufferResult=JSTSBufferOp.bufferOp(bufferCenter,10)//instanceofGeometryconstbufferResultGeoJSON=newJSTSGeoJSONWriter().write(bufferResult)如果不熟悉它的包结构和JTS的用法,不建议直接使用jsts。3.2.GeoJSON的简单“地盘”-@terraformer/spatial当我在上面介绍WKT库时出现了这个@terraformer帐户。该库可以轻松地对GeoJSON对象执行简单的空间分析。可以说是简单版的turf:pnpmadd@terraformer/spatial其类型库需要额外安装@types/terraformer__spatial-D。它有applyConverter(GeoJSON特征顶点遍历器)、intersects、convexHull、contains等非常简单的分析函数,见其README文档。3.3.其他一些几何变换和计算类库这些几何类库的“GIS”血统比较薄弱,但辅助使用还是可以的。TypeHintLibrarySizeRichnessDocumentPurposeSuggestedadditionalinstallationofearcut95.2KB完整的特定功能离散几何多边形的三角剖分以生成三角形网格107KB适度完整和简单的几何计算,替换一些草坪需求@flatten-js/corets源代码5.68MB丰富和更复杂的几何图形的完美几何计算基于earcutsimplepolygonNo36.6KB专门用于处理GeoJSON。将复杂(即自相交)的GeoJSON多边形分解为复合的简单、非自相交的单环多边形。请参阅README3.4。几何空间分析库总结其实这些库是远远不够的。开源社区总能淘到宝,但要够用。为什么我没有列出地盘?因为turf的算法精度和性能实在是高不可攀。群里的朋友反映了这个问题。如果你不能使用它,你应该尽量不要使用它。而且,我觉得还是把复杂的几何计算交给后台计算程序比较好,前端计算毕竟有限。4.地图库扩展4.1.ol、mapboxgl、leaflet.js的扩展绘图工具-terra-draw这个库是前端地图库(支持OpenLayersV7、Leaflet.jsV1.9、MapboxGLV2、MaplibreV2、GoogleMapAPIV3)插件,用TypeScript编写,带有完整的文档和在线示例。pnpmaddterra-draw在我写这篇文章时仍处于alpha阶段,但可用性非常好。官方示例引导方式:TerraDraw4.2。leaflet.js扩展的绘图工具如题。这个绘图插件非常强大,基本可以满足大部分的二维绘图需求,体积也达到了450KB+。pnpmadd@geoman-io/leaflet-geoman-free是用TypeScript编写的,支持多种语言,并且有非常全面的文档。但是,它内置的按钮可能不适合某些场景(如果你想自定义按钮样式和UI逻辑)。总的来说我给它98分。5.杂项5.1。中国大陆行政区划代码库就像一本字典,适用于小型项目(不具备调用数据库接口的条件)。pnpmaddchina-region也有类型提示的版本china-regions-ts,不过我个人建议找这类管理代码库的时候,尽量找最新的版本。5.2.GeoJSON的增强类型提示-@types/geojson可以替换TypeScript项目中所有级别的GeoJSON对象的任何问题。请注意,它必须作为开发依赖项安装。这东西只是一个类型库。pnpmadd@types/geojson-D易于使用:从'geojson'//导入类型{Polygon}...5.3。类似WFS的OGCFeatureAPI客户端实现库-@ogcapi-js/featuresOGCAPI是我之前写介绍性介绍时说的,是OGC正在制定和推动的下一代GIS网络规范,涵盖了方方面面。其中OGCFeatureAPI是WFS的下一代规范,也就是原定的WFS3.0。当满足OGCFeatureAPI的服务启动时,可以使用该包调用OGCFeatureAPI规范定义的函数。当前的OGCAPI尚未完全确定。以最新版本为准。您可以在@ogcapi-js账号下关注新包。pnpmadd@ogcapi-js/features的用法也很简单。import{Service}from`@ogcapi-js/features`;//创建服务对象constservice=newService({baseUrl:'https://ogcapi.service.com'});//调用接口获取数据集列表constcollections=awaitservices.getCollections();5.4.操作Esri的投影定义对象这是一个针对Esri用户的小工具,但也适用于一些需要坐标系WKT的场景。它暴露了一个查找函数,传入WKID来查找坐标系对象:pnpmadd@esri/proj-codes这个包稍大,如果不需要,不要使用它,查找坐标系的工作应该由后端数据库。从'@esri/proj-codes'constcrs=codes.lookup(3857)crs.name//'WGS_1984_Web_Mercator_Auxiliary_Sphere'crs.wkt//'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984"...'导入代码。description//'WGS1984WebMercatorMajorAuxiliarySphere'crs.authority//'EPSG'crs.deprecated//'no'crs.extent//{"slat":-85.06,"nlat":85.06,"llon":-180.0,"rlon":180.0}//thisworkstoocodes.lookup(3857).name//'WGS_1984_Web_Mercator_Auxiliary_Sphere'6.总结本文主要关注浏览器前端。其实一些库在NodeJS的后端也是可以使用的,比如坐标系,格式转换,几何空间分析等,还有一些单独针对NodeJS后端的,还有更多的数据库,格式转换和图像算法,但它们已逐渐从GIS谱系中淡出。有机会再介绍一下吧。
