好久没更新了,因为我在--憋--大--招--,对,就是今天这篇。

今天跟大家分享一下我的开源GIS解决方案经历。

--额-- 考虑到单聊技术解决方案你可能会很快睡着,所以我今天会把重点放在我封装地图API这个事情上,以封装地图API的经历为线索,穿插着讲一些当时用到的开源GIS架构。

文章稍微有点长,如果你只是想了解一下最新的开源GIS架构,可以直接跳过前面,去看第五版和最后的总结,但我建议你还是从第一版开始看,因为没有前面的 4 个版本就不会有第五版,只看总结就和读名言警句效果一样,看的时候觉得有道理,过后就忘了,因为不能感同身受。

缘起

我一直在传统IT行业的公司工作,公司都是以做政府项目为主,俗称toG业务。

这种公司里,GIS在其中的应用通常为两种,一种是GIS结合公司的业务形成一个xx地理信息系统,或是xx一张图系统,另一种是结合公司业务封装一套地图API,为公司的其它业务系统提供地图技术支撑,类似于高德地图API、百度地图API。地图API的背后通常有一套GIS解决方案作为支撑

今天我们就来聊一聊封装地图API这点事。

从我封装的第一个地图API版本诞生到现在,已经过去了7年时间,中间经历了 3 家公司,迭代了 5 个版本。5 个版本中,第 1 个版本使用的ArcGIS,后面 4 个版本主要使用的开源GIS。

第一版 2014年

背景

公司做环保业务,业务系统主要用C#开发,业务系统中涉及地图的部分使用ArcGIS Flex API开发,由GIS开发人员负责。那个年代,地图还主要是用Flex开发,因为Flex在那时给人感觉是很炫酷。

随着项目的增加,发现很多业务功能在项目里是通用的,再后来发现,如果把业务功能和地图功能分离,再把Flex编写的地图功能封装一套面向JS的接口,C#开发人员就可以自己完成地图相关的工作,不用受Flex语言的限制了。

于是我们准备封装一套用Felx编写的,面向C#开发人员的JS地图API。

技术架构

  1. 前台使用ArcGIS Flex API开发地图功能,Flex支持和JS交互,利用这一特性将Flex开发的地图功能,封装成面向JS的接口。
  2. 地图后台使用 ArcGIS Server,空间分析使用 GP 服务。
  3. 空间数据库使用 Arc SDE。
  4. 开发了一个简单的帮助网站,提供前台JS接口的调用示例和使用说明。

经验总结

地图API发布后,在做技术支持的过程中发现一个有趣的现象,关于地图API的使用,完全不懂GIS的初级C#开发人员觉得好用,原因是能帮他们解决问题,有困难时可以随时找我们技术支持。

了解一点GIS的中级C#开发人员觉得不好用,他们会拿我们的地图API和ArcGIS JS API对比,觉得后者更好用,但由于ArcGIS JS API的地图偏丑,我们也不提供技术支持,需要他们自己去研究,最终还是选择用我们的地图API。

了解一点GIS的高级C#开发人员基本不用,其中有两个同事的反应令我印象深刻,一个同事说:”你们自己开发的东西,自己都不用“。言外之意是,你们自己都不用的东西不会好用。但我们的想法是,把Flex封装一套JS的地图接口是因为Flex入门有门槛,我们GIS开发人员既然都会Flex了,而且我们开发的地理信息系统,整个都是用Flex开发的,那肯定是直接用ArcGIS Flex API会更灵活,所以不用。

还有一个同事更牛,他直接去研究Flex,不会的就问我们,入门后直接封装了一套地图接口自己用。我们研究过他封装的接口,虽然功能简单了些,但定义接口时的出发点感觉明显和我们不一样,我们是站在功能的角度封装,尽量保证接口的复用度高,比如添加点,添加线,缓冲等功能。他是站在用户的角度封装,比如从数据库查出来一堆数据,把这堆数据直接丢给接口,就在地图上展示出来了。总体而言,他的接口封装度更高,更贴近他的实际使用习惯,而我们的接口更像是把ArcGIS的Flex接口翻译了一套JS的。

还注意到一个现象,经常有使用我们接口的业务开发人员跑过来问,为什么我的地图不显示?经历的多了,发现通常有两种原因,一种是地图服务的地址不对,当时的地图服务都是用ArcGIS server发布的,ArcGIS server地图服务的rest地址是个网页,这个网页打开后,有很多级的链接地址,业务人员不知道应该拷贝哪一级的地址,经常拷错,所以地图出不来。另一种是,添加多个地图时,地图间的坐标不一致,导致添加的地图不显示。

想想也是,地图服务和地图坐标这些知识对于不懂GIS的开发人员来说还是挺难的。

虽然第一版有这样那样的问题,但在当时还是提升了部门的整体工作效率。不光是C#开发人员可以自己去开发地图功能了,GIS组内部也通过这种形式,把分散在各个项目中的技术成果收集了起来,并不断的积累完善。

第二版 2016年

背景

换公司了,新公司做网安业务,有海量定位数据,GIS在其中的作用是,对定位数据进行提取、分析、展示,从而帮助客户解决业务问题。

公司的所有系统必须部署在客户内网,客户的内网是无法访问互联网的,而地图使用的又是互联网地图,这就需要把互联网地图瓦片下载下来,拷贝到客户内网发布。

公司有一个GIS应用系统,和GIS强关联的业务功会能放在这里。另外,其它部门有地图功能需求时,也会找到我们GIS部门,这个场景和上家公司很像。

所以,二话不说,第二版地图API走起。

技术架构

  1. 这一版开始使用开源GIS。GIS前台选择了openlayers,有了第一版的经验,这一版重点解决了地图资源问题,和地图坐标问题。

    1. 解决地图资源问题。统一管理底图资源,提供多种互联网地图,包括高德地图、谷歌地图、天地图等,每种地图有个id,初始化地图时,根据id使用不同的底图。
    2. 解决地图坐标问题。对外统一使用wgs84坐标,地图API内部负责将wgs84坐标转换为和底图匹配的坐标,包括gcj02坐标、bd09坐标等。
  2. GIS后台方面,因为定位数据都存放在大数据框架的数据库中,后台只有互联网离线地图瓦片需要发布,所以直接使用了tomcat发布瓦片,再在openlayers中写一个加载本地瓦片的功能,这就算GIS后台了。
  3. 没有使用空间数据库,空间分析使用ArcGIS Engine开发控制台程序,再用Java后台调用控制台程序。
  4. 接口写了详细的说明文档和调用示例。没有做包装,直接是word文档+html示例文件。

经验总结

  1. 解决地图资源和坐标问题,可以大大提升用户体验。
  2. 关于地图下载器,虽然大家都有能力自己写一个出来,但真的挺不划算的,最好的解决方案就是花公司的钱去买一个许可,站在公司的角度这都没几块钱。
  3. ArcGIS Engine的版本,C#版的比较稳定,Java版的超级难用,非常不稳定,动不动就死给你看,更不要尝试去把它部署到Linux服务器,不要问我是怎么知道的。我当时为了在linux上部署,先开发了一版java的,部署后一天崩溃好几次,动不动就内存溢出,根本没法用,没办法只能重新写了一版C#的部署在windows服务器上。

第三版 2017年

背景

换公司了,新公司做管网业务,相比前面两家,业务和GIS的相关性更强一些,业务中需要对管网GIS数据进行编辑、存储、发布和应用。公司之前地图都是使用ArcGIS开发的,正在准备转开源GIS,于是我到公司后就顺理成章的开始了第三版地图API的开发。

在开发之前,我先仔细研究了高德和百度地图API,并问了自己两个问题:

一、为什么非GIS开发人员,能够用高德、百度地图API解决问题,却用不了ArcGIS,openlayers,leaflet?

二、非GIS开发人员在用互联网地图API时遇到了哪些问题?

下面是我自己的理解:

第一个问题是因为:1、非GIS开发人员不需要自己发布地图数据,地图都是官方提供的,只管用就行。2、互联网地图API的帮助文档和示例都是中文的。

第二个问题,我自己尝试使用后发现:1、互联网地图API的离线使用是个问题,它们都只能在线使用,如果遇到不能访问互联网的情况,就无法使用了,这问题在toG业务中还是挺常见的。2、互联网地图API只能用官方提供的地图坐标,不能集成其它坐标的地图资源。

从这一版起,我们开始尝试在用户体验上对标高德、百度地图API,学习对方的优点,避免对方的问题。

技术选型

GIS前台没有再继续使用openlayers,而是转向了更为轻巧的leaflet,当时的考虑是:

  1. leaflet很小巧,核心代码结构简单容易理解,可塑性强,适合拿来改造为自己的API。
  2. leaflet可以同时兼容web端和移动端。
  3. 有esri维护的leaflet插件,能更好的兼容公司之前发布的ArcGIS地图服务。

GIS后台选择了geoserver。因为geoserver的资料比较丰富,能同时支持postGIS和SDE空间数据库。

GIS空间数据库选择了 postGIS,空间分析也主要使用 postGIS 的空间分析函数实现。

桌面端开发继续使用ArcGIS Engine,没有去尝试QGIS,主要原因是,公司之前在ArcGIS Engine上有大量的技术积累,已经形成了成熟的产品,转换成本会很高。

技术架构

在leaflet的基础上封装了一层自己的接口,原生leaflet接口不对外,当时的考虑是:

  1. 和上一版一样,封装后容易解决互联网地图偏移的问题,对外统一使用wgs84坐标,内部根据不同的底图将数据转换为对应的坐标。
  2. 可以实现类似JQuery那样的扁平化接口,简单易用。
  3. leaflet中点的写法是[纬度,经度],而我们通常更习惯使用[经度,纬度]的写法,可以通过封装顺便解决这个问题。

当需要复杂的GIS空间分析时,编写geoserver的扩展插件,插件连接PostGIS数据库,通过使用PostGIS空间分析功能,自己编写函数完成空间分析工作。

基于geoserver的rest接口实现地图服务的自动发布。在ArcGIS Engine开发的桌面软件中,先将GIS数据导入到空间数据库,再调用geoserver的rest接口发布地图,最终实现的效果和ArcGIS发布地图的体验相同。

搭建一个门户网站,内容包括帮助文档、地图资源、更新说明等,帮助文档以接口为线索,接口内部有接口说明和调用事例。地图资源中提供可以使用的所有地图,包括互联网地图和自己发布的业务地图,每个地图有个id,根据id就可以在API中轻松加载地图,不需要关心地图服务是如何发布的。

将PostGIS、geoserver、tomcat全部修改为绿色版本,方便项目部署。

经验总结

  1. 可以使用SLDEditor软件解决geoserver不容易配图的问题。geoserver的配图不好用,尝试了在QGIS上配图,然后发布到geoserver上,发现QGIS上配图后生成的sld样式文件格式,有很多geoserver都不支持,也不知道是版本没对应上还是其它原因,最后找了个开源工具SLDEditor来编辑样式文件,完美解决问题,但整体的使用体验跟ArcGIS差很多。
  2. PostGIS的空间分析功能很好用、很强大。所以空间分析功能,我们就主要用PostGIS来实现了,比如之前分享过的图形缓冲功能
  3. geoserver扩展更适合开发和生成地图服务相关的功能。GIS的空间分析功能一开始通过geoserver扩展插件实现,后来发现扩展插件的后台程序主要作用是数据传输,最主要的分析环节是在空间数据库PostGIS中实现的,而geoserver的扩展开发环境比较复杂,不如自己写的java后台好维护。geoserver扩展的优势是可以直接调用geoserver的资源和功能,它更适合开发和生成地图服务相关的功能。

第四版 2019年

背景

开发出第三版后,在部门中使用了一年多,整体反应良好,有一部分懂GIS的同事,之前使用的ArcGIS JS API,用了leaflet封装的上一版地图API后,他们的第一反应是这个好轻便,比ArcGIS JS API 小了好多,加载很快。

上一版发布后,我们留意了用户的使用习惯,大家的使用习惯基本都是先看示例,找到示例后,会直接把代码拷走使用,当示例不完全满足要求时,再去翻看API说明,最好的情况就是示例代码注释完善,一眼就能看懂,拷过来就能用。

当然在使用的过程中,也慢慢发现了一些问题。

懂GIS的同事反馈最强烈的是,能不能把原生接口放开。有个同事,每次都会先自己在网上找leaflet代码,确认能实现了再来找我们,让我们添加这个功能,甚至把资料链接都发过来了,整的我们都挺不好意思的。如果能把leaflet原生接口放开,有很多工作他自己就能解决了。

然后是我自己,当我需要研究一个新功能时,我的第一反应不是去用我自己封装的地图API,而是更愿意使用原生leaflet去写,因为是我觉得自己封装的地图API用起来不够灵活。

天呐!!!

这不就和第一版时,同事说:”你们自己开发的东西,自己都不用”,是一样一样的嘛,如果说第一版时还有Flex语言的因素,那这第三版从内到外都是JS写的,没什么好解释的,就是让人家说中了。

我们平时的工作,除了封装地图API,我们还有其它工作要做,上一版中,感觉我们很大一部分精力被消耗在了封装基础功能这件事上,导致没有时间去研究高级地图功能。如果能把原始接口放开,基础功能就可以直接使用原生接口,我们就有更多时间去研究高级地图功能。

能不能放开原生接口?

要放开原生接口面临几个问题:

  1. 地图坐标偏移问题。

    之前通过封装,在对外接口和地图之间构建了一个坐标适配层,解决了坐标偏移问题。如果放开原生接口,就没有办法再使用这方式,需要想其它办法。
  2. 用户使用习惯问题。

    不懂GIS的用户会不会习惯了扁平化接口,放开后觉得原生接口不好理解?leaflet中点的写法是[纬度,经度],和平时使用的[经度,纬度]不同,会不会有人适应不了?
  3. 版本向前兼容问题。

    上一个版本中为了追求接口的极简性,简化了很多数据格式类型,如果放开原生接口后,还要兼容这些格式将会产生很大的工作量,而且后续每增加一个功能都要考虑兼容这类数据的问题。

解决方案:

  1. 针对坐标偏移问题。

    有两个方案,一是给用户提供一个坐标转换的接口,用户自己来转换坐标,但这样对用户不友好。二是对互联网地图瓦片进行纠偏,让地图统一坐标,不再偏移,这是最理想的,但有技术难点。不过,我们最终还是攻克了技术难点,采用了第二种解决方案,详见:leaflet中如何优雅的解决百度、高德地图的偏移问题

  2. 针对用户习惯问题。

    为什么百度、高德的地图API并没有使用扁平化接口,大家也没有觉得它们难用?我们研究后得出的结论是:在接口没有特别复杂的前提下,地图API如果能做到:能解决用户问题,bug少,示例丰富,说明文档清晰,大家就会觉得好用。接口是否是扁平化其实不怎么重要。而且,leaflet的原生接口本身就已经非常简洁了,单从简洁性考虑的话,没必要再封装。

  3. 针对版本向前兼容问题。

    我们决定不对上一个版本兼容,让两个版本同时保留,慢慢过渡,新项目新产品推荐大家用这一版,老项目我们继续提供技术支持,但不再做功能升级。这样经过1、2年后,就能慢慢切换过来。事实证明这个决定是对的,现在已经过去2年多时间,部门里大部分系统都已经切换都了新版本。

技术架构

技术架构在上一版的基础上做如下调整:

  1. 放开leaflet原生接口,不再对接口进行封装,改为以插件形式进行功能扩展。
  2. 集成多种互联网地图资源,通过对瓦片纠偏的方式解决它们的坐标偏移问题,对外统一使用wgs84坐标。
  3. 帮助文档由接口为线索改成以示例为线索,示例中的注释保证完善清晰,将示例代码中用到的方法给出类参考链接。
  4. 将leaflet的类参考文档进行翻译,放到平台中。
  5. 当有新的功能需求时,简单的功能不封装,直接给出示例,复杂的功能再考虑封装到插件中。
  6. 和geoserver相关性不强的地图分析功能,迁移到java后台,geoserver中只保留和制图相关的功能。

经验总结

  1. leaflet类参考的翻译工作没做好,一共没翻译几页,但奇怪的是大家从来没有抱怨过这个问题。后来观察发现,用户基本不看文档,更多的是看示例,示例没有的,会直接问我们,文档其实只有我们在看(捂脸)。
  2. 有人问问题时,尽量以示例的方式记录下来,后续大家在示例中能找到这个问题就不会再问了。
  3. 调用示例的名称目前是文字列表形式,文字毕竟有表达上的局限性,对比高德、百度地图API,他们在示例列表的前一步,用动图的方式直接展示示例的最终效果,这样更加直观容易理解。
  4. 要尽量通过工具,让平台的维护变得简单,太复杂自己就不爱维护,最后平台容易废掉。

第五版 2021年

背景

这一版还没有完成,年前刚做完技术预研工作,这里先把整体的思路简单和大家分享一下。

总的来说,上一版已经很好用了,现在已经很少有来自用户的负面反馈。产品还曾在大项目中作为技术中台,提供给其他公司使用,同样效果很好。

但我们自己还是有追求的,和高德、百度地图API相比,我们在下面几点上还需要改进:

  1. 地图美观度问题。

    地图的底图目前都是使用互联网地图瓦片,叠加上业务数据后,会遮盖底图中的注记,业务数据间的注记也不容易实现自动避让,再加上没有好用的地图配图工具,导致地图在展示多样数据时就会显得很乱、很丑。
  2. 展示性能问题。

    地图有时需要一些动画效果,比如用动画效果表达管网中水的流动方向和快慢,在数据量较大时会出现明显的卡顿。
  3. 地图配图问题。

    geoserver配图不好用,这个问题前面已经提到过,虽然使用SLDEditor可以生成配色文件,但一次只能生成一个图层,没有办法整体预览,效率太低,体验太差。高德、百度地图的自定义地图配图工具就很好用,美工可以直接上手,眼馋很久了。

这一版的目标是解决上面3个问题,并继续优化用户体验。

技术选型

前台改为使用mapboxgl,不再使用leaflet,原因有两个:

  1. 性能。leaflet的上限在10万左右(详见:leaflet如何加载10万数据),而mapboxgl基于webgl技术开发,最大数据量取决于显卡性能和网络传输速度,理想情况下可以轻松达到百万级别。
  2. 美观度。mapboxgl对矢量瓦片支持特别好,再结合maputnik可以轻松实现高德、百度地图的自定义地图功能。

地图配图使用maputnik,业务数据使用geoserver发布矢量瓦片,正常maputnik是不支持geoserver发布的矢量瓦片的,不过我们已经把这个问题解决了,详见:如何让矢量瓦片配图神器maputnik支持 geoserver

底图数据有两种方案:

  1. 继续使用互联网地图栅格瓦片,适合对底图数据准确性要求较高的情况。
  2. 在本地发布OSM矢量瓦片地图,目前网上没有可以直接使用的免费矢量瓦片资源,只能自己把OSM数据下载到本地自己发布。OSM地图在国内的数据质量比较差,如果你的业务对底图数据的准确性要求不高,对样式要求比较高,比如大屏展示系统,可以选用这个方案。具体方法详见: 如何实现OSM地图本地发布并自定义配图

地图可视化效果使用deck.gl、L7来实现。

经验总结

  1. 使用maputnik同时加载geoserver发布的业务图层和本地发布的OSM底图,可以实现业务数据和底图的深度融合,比如把业务数据中的河流放到底图道路图层的下方,并实现标签的自动避让功能,类似这样的体验还是非常爽的。
  2. OSM地图的合规性存疑,建议自行将中国的国界线校准一遍再用。

后续展望

  1. 解决OSM地图数据量少的问题。

    第五版解决方案有一点不完美的地方是,OSM地图在国内的数据量较少,这也是在我年初的Flag中,想要通过机器学习自动提取建筑物轮廓的起因。

  2. 研究三维GIS。

    之前的工作一直是二维GIS,三维GIS的业务比较少,也研究了cesium、ArcGIS js API 4.x、three.js 等,并在项目上有过使用,但对三维GIS的整体理解还是不像二维GIS那样通透,不能像二维GIS那样信心十足的给出一个自己满意的开源解决方案,所以在这块儿需要继续努力。

总结

关于地图API

在toG业务的公司中,想要通过开源GIS,打造一套在易用性上比肩高德、百度地图的API,需要注意以下几点:

  1. 解决地图资源问题。把网上的地图资源整理好,把项目上的业务地图资源整理好,对外让用户可以直接使用。
  2. 解决地图坐标系问题。要搞定互联网地图的偏移问题,和多种地图坐标间的转换问题,对外让用户只使用一种坐标。
  3. 基础地图功能通过用户教育的方式实现,也就是提供完善的调用示例和说明文档。高级地图功能通过封装插件的方式实现,这样可以避免随着时间的推延,核心API越来越冗余。
  4. 场景丰富的、可以直接使用的调用示例,比接口是否简介、文档是否详细更重要。
  5. 用户觉得地图API是否好用的影像因素,从高到低排序:能不能解决问题、有没有bug、有没有丰富的示例、技术支持是否到位、文档是否清晰。
  6. 己所不欲勿施于人。找一个真实的业务场景去使用自己的API,并不断的从中发现问题,解决问题,完善功能,直到自己觉得非常好用为止,这样可以强迫自己站在用户的角度去思考问题。如果自己都不愿意去用,那就肯定是不好用,最终不会走的长远。
  7. 要做好技术支持工作。开发地图API需要一个长期的、持续迭代的过程,这个过程中难免有这样那样的问题,如果你的用户支持好,它能帮你弥补那些问题给用户带来的不好体验。
  8. 学会通过工具提高平台维护效率。多去想想平台维护的过程中,哪些环节可以通过自动化或半自动的方式完成,比如生成文档环节、更新部署环节等,节省了时间好去研究更深层次的东西。

关于开源GIS解决方案

下面是我推荐的两种组合方案,其实都是前面提到过的,这里汇总一下。

轻量版:leaflet + geoserver + postGIS

这个组合网上的资料多,软件简单易用,普适性强,能满足绝大多数人对二维GIS的需求。

矢量瓦片版:mapboxgl + maputnik + geoserver + postGIS + openmaptiles + three.js

这个组合可以搭建出一套类似高德、百度地图的自定义地图,也可以实现白模三维地图,如果你比较看重地图可视化效果,那么推荐你使用这一套。

好了,就到这里吧。如果觉得对你有帮助,可以通过持续关注和多多分享来支持我们。


原文地址:http://gisarmory.xyz/blog/index.html?blog=GISerSolution

关注《GIS兵器库》, 第一时间获得更多高质量GIS文章。

本文章采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名《GIS兵器库》(包含链接:  http://gisarmory.xyz/blog/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

我的开源GIS解决方案之路的更多相关文章

  1. .NET 开源GIS解决方案一 概述

    写在前面 最近开始研究开源GIS,国内开源GIS的资料很少,而基于.net的又是少之又少.所以决定把自己研究的资料进行总结整理,技术在于分享,本系列(计划是写一个系列,如果我可以坚持下来的话)部分是自 ...

  2. GIS项目中数据开源、工具开源、开发开源的解决方案

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 摆脱免费地图开发包的约束,拒绝商业地图软件的费用,高效.精确.完备是我 ...

  3. 开源GIS软件初探

    谈到GIS软件,首先让我们想到的便是GIS界的龙头大哥ESRI公司旗下的ArcGIS产品,从最初接触的version 9.2到如今的version 10.1,其发展可谓风生水起.MapInfo软件也不 ...

  4. 开源GIS简介

    原文 开源GIS C++开源GIS中间件类库: GDAL(栅格)/OGR(矢量)提供了类型丰富的读写支持 GEOS(Geometry Engine Open Source)是基于C++的空间拓扑分析实 ...

  5. 开源GIS简介.学习

    开发者都希望自己的软件能够运行在尽可能多的计算机上.然而事与愿违,摆在 GIS开发者面前的仍然是对峙的平台.J2EE随着Java5.0的发布,已经正式更名为JavaEE,而微软也正式发布了.NET2. ...

  6. 开源GIS浅谈 【转】

    http://blog.csdn.net/happyduoduo1/article/details/51773850 谈到GIS软件,首先让我们想到的是GIS界的龙头大哥ESRI公司旗下的ArcGIS ...

  7. 开源GIS软件 1

    1. 在线地图浏览器 GMap.NET GMap.NET 是一个强大.免费.跨平台.开源的.NET控件,它在Windows Forms 和WPF环境中能够通过Google, Yahoo!, Bing, ...

  8. [置顶] 遵循Java EE标准体系的开源GIS服务平台架构

    传送门 ☞ 系统架构设计 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 传送门 ☞ GoF23种设计模式 ☞ 转载请注明 ☞ http://blog.csd ...

  9. 也谈开源GIS架构实现思想

    针对业务发展需要,需要开发设计一套具备自己独立GIS平台.然而以ArcGIS为主的GIS软件价格昂贵,在经过仔细技术与市场动向调研后,确立一套以Java语言的开源GIS软件平台.桌面CS端Udig+G ...

随机推荐

  1. how to design a search component in react

    how to design a search component in react react 如何使用 React 设计并实现一个搜索组件 实时刷新 节流防抖 扩展性,封装,高内聚,低耦合 响应式 ...

  2. JavaScript 如何使用 setTimeout 实现 setInterval

    JavaScript 如何使用 setTimeout 实现 setInterval website multi content page setIntervalSimulator "use ...

  3. JavaScript Number Type Checker

    JavaScript Number Type Checker Number.isInteger // static 方法 Number.isInteger(value) https://develop ...

  4. flex & flex-wrap

    flex & flex-wrap https://css-tricks.com/almanac/properties/f/flex-wrap/ https://developer.mozill ...

  5. qt 注册热键

    原文 将所需的库添加到您的qmake项目(.PRO文件) LIBS += \ -lUser32 2.在代码中包含所需的头文件. #include <windows.h> 在程序开始时注册热 ...

  6. APC推出鞋底缓震科技 两款中高端跑鞋将陆续上市

    近日,英国知名运动品牌APC(公司编号:08703733)推出了全新的鞋底缓震科技 NOVR,该项技术将首先应用于两款跑步鞋上,随后陆续应用到其他重点鞋类产品. 是对于各大运动品牌来说,鞋底研发一直是 ...

  7. JVM参数概述

    标准参数(-) 所有的JVM实现都必须实现这些参数的功能,而且向后兼容. 通过命令 java 查看如下: 用法: java [-options] class [args...] (执行类) 或 jav ...

  8. java荷兰国旗问题

    荷兰国旗包含三种颜色:红.白.蓝. 有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列.它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素.等 ...

  9. Redis基本数据结构之ZSet

    1.1Zset(有序集合) Zset保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序.但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作为排序的 ...

  10. JavaScript async/await:优点、陷阱及如何使用

    翻译练习 原博客地址:JavaScript async/await: The Good Part, Pitfalls and How to Use ES7中引进的async/await是对JavaSc ...