GeoPuzzle-一步步打造世界

图片

我想谈谈过去几年中一直在开发的项目。 它被称为GeoPuzzle ,是世界政治地图上的一款益智游戏。 我们的目标是将部分国家置于其位置。 这个想法出现在文章“针对地理专家的墨卡托拼图”中 ,也曾在童年时期演奏过来自俄罗斯(仍在DOS下)的俄罗斯方块,但我不记得该程序的名称。 我受这个想法的启发,以至于我想制作一个完整的产品,不仅对学童而且对地理专家都很有趣。 该项目的开发可以在GitHub上进行观察。

样机


2013年2月8日发布了文章“地理专家的难题墨卡托”,但4个月后,我准备了一个原型,其中组装了世界所有国家的多边形。 稍后,我添加了俄罗斯和美国各州的区域,并随机选择了地图上初始位置的选择。 我在博客中描述了开发过程,并将源代码发布在GitHub上 。 就是这样-卡住了。 我的空闲时间减少了很多,我的动力消失了(没有做出决定),并且复杂性成倍增加。 这是一个宠物项目,主要任务是学习新知识,所以我对技术有些不满意。 当然,在客户端上,使用javascript(那时我并没有做太多工作),ruby脚本(同样是我的一种新语言)负责数据的准备,但是在服务器上是erlang(我想尝试一些纯粹的功能)。 从舒适区完全退出:很难直接使用PostGIS对象,将字符串转换为erlang的痛苦,配置YAWS完全是一个单独的问题...在下一阶段,我意识到我无法应付所有这些动物园来制造出完整的产品,于是离开了想了几年。

GeoPuzzle


图片

这个站点一直都在工作,人们甚至都去过那里,但是我真的很想增加一个小细节:至少显示一些有关新发现的多边形的信息。 因此,我计划在2017年度过新年假期。 由于原型中的问题,我决定重写所有内容,然后将产品制作为熟悉的东西-Django。 开箱即用的东西极大地简化了我的生活,例如管理面板和通过ORM使用PostGIS。 但是对于初学者来说,有必要重新创建已经起作用的功能。 只花了几个晚上,大部分时间是从KML文件中加载数据。 与其说是导入过程本身,还不如说是他们准备和恢复我如何与他们合作的知识。 顺便说一句,我当时从gadm.org提取多边形 。 这对于国家/地区来说效果很好,但是区域的准确性存在某些问题,因此我为此超时。

关于地理数据管理级别(级别)的几句话。
所有国家都分为许多区域,每个区域甚至更小。 这样的层次结构总共有12层。

例如,对于俄罗斯:

  • 俄罗斯(2)->南部联邦区(3)->克拉斯诺达尔地区(4)->维塞尔科夫斯基区(6)->艺术。 村庄(8)
  • 俄罗斯(2)->南部联邦区(3)->克拉斯诺达尔地区(4)->克拉斯诺达尔(6)->普里库班斯基区(9)->科潘斯卡亚(10)
  • 法国(2)->法国大都会(3)->诺曼底地区(4)->奥恩省(6)-> Donfron州(7)-> Donfron-en-Poiret自治市(8)-> Donfron(9)

不同国家/地区的地域单位以他们自己的方式来称呼,但对我自己来说,我推导出了这一划分:国家(2)->地区(4)->地区(6)。 进一步的行政区划留给以后。

项目开发


那时,该应用程序只是HTML页面的集合,其中包含最少的CSS。 我想快速检查一下想法,而不是去理会设计。 这个想法原来是可以实现的,是时候为它做一个漂亮的外壳了。 因为 我在UI中没有美感,然后通过Bootstrap来帮助我。 没有接口,但它出现了,甚至适用于移动设备。 但这只是使前端井然有序的第一步。

在2016年学习JavaScript感觉如何 ? 当代码被编译成另一种方言时,它被模板化,粘在一起,以便以后可以切成碎片。 作为后端,我很害怕,但是客户端部分的复杂性计划得足够大,这就需要使用框架或库。 我选择React的原因有两个:我不需要SPA,但是需要一组用于不同页面的组件,并且我想快速查看结果。 但是在开始编程之前,您必须设置环境。 现在,我了解了熟悉的前端,他说他设置了2天的Webpack。 事实证明这不是在开玩笑。

那时,我屈服于劝说,并使用Redux实现了应用程序的逻辑。 也许这不是一个错误,因为 允许快速输入主题。 正式的规则使我可以编写代码,并确保它可以正常工作而不会在幕后看。 Redux使用其中间件使我从网络交互中抽象出来,这使我可以检查对服务器的响应。 是的,到目前为止,客户端自己进行工作-ajax请求提取了所有必要的数据并自行检查了答案。 用户可以通过查看来自服务器的数据来作弊。 此外,在加载时,只有在给出正确答案之后才有必要输入数据。 通过Web套接字实施验证后,该过程在意识形态上变得更加正确-答案将验证客户端不可用的代码。 对于用户而言,这仍然是瞬间的:将多边形的极端点发送到服务器,检查它们是否进入了错误的正方形,将信息框和详细多边形的数据打包到json中并将其传输到客户端-大约200毫秒之内。

图片

了解了javascript的所有功能之后,就很难停止了。 立刻有了在哪里添加动画,折叠块,眨眼和新版本游戏的想法。 其中之一就是“测验”,您必须在其中用名称,旗帜,徽章或首都猜测国家。 但是,在测试过程中,结果发现某些地区没有标志,而其他地区没有首都,因此必须将某些国家从可用国家列表中隐藏起来。 同时,对于真正的职业玩家来说,游戏模式出现在世界的物理地图上-没有国家的边界​​。

开放数据源


现在游戏中大约有50,000个多边形,我要对维基百科和开放街道地图这样的伟大项目表示由衷的感谢,如果没有这些项目,就不可能填补基础。 基本要求是从开源接收和更新数据,也就是说,无需手动编辑,因为 我不想做复杂的同步逻辑。 结果,我得到了2个可以更新信息框和多边形的脚本。

维基百科和SPARQL


图片

什么是最大的国家和地区数据库? 维基百科! 最初,我想向用户展示整个信息框,但很快就放弃了这个想法。 是的,有一些重要的东西,例如名称,旗帜,大写字母和其他东西,但也有很多垃圾(电话代码,政府机构,GDP等等)。 我试图解析已经收集的内容,但是发现它们具有不同的结构。 事实证明这是一场灾难:实施的人工成本增加了很多倍。 现在该停下来思考。 第二天,我了解了一种特殊查询语言-SPARQL的存在。 在外观上,它类似于SQL-也是声明性的,带有关键字SELECTWHEREORDER BY ,但是它的工作方式完全不同。 一个小示例返回以英语和俄语显示其大写字母的州列表:

 SELECT DISTINCT ?country ?capital ?row WHERE { ?country wdt:P31 wd:Q3624078 . FILTER NOT EXISTS {?country wdt:P31 wd:Q3024240} OPTIONAL { ?country wdt:P36/rdfs:label ?capital } . BIND(lang(?capital) as ?row) filter (?row = 'ru' || ?row = 'en') } ORDER BY ?capital 

看起来很野,不是吗? 在这里检查。 我什至在我的博客上写了一条便条纸,以某种方式构建我的经验并帮助您进入该主题,因为 互联网上很少有详细资料。 您可以很快地学会阅读此类要求,但是我花了整个周末才写出有意义的东西。 来自wd:Q3624078许多“魔术” wd:Q3624078和其他属性。 您需要知道wdt:P31是“实体”,而wd:Q3624078是“主权国家”。 未知的人以问号开头,请求的满足在于寻找满足条件的三重事实。 例如?country wdt:P31 wd:Q3024240 “查找所有具有历史状态的对象”; 然后同一对象又参与其他三元组( ?country wdt:P36/rdfs:label ?capital

大约一周后,我准备了脚本的第一个版本,该脚本从Wikipedia下载了区域信息。 然后另一个问题变得很清楚-这次是数据。 某些svg并非以<?xml version="1.0" encoding="UTF-8"?>开头,并且被浏览器识别为无效图像。 幸运的是,可以编辑源文件。 在Wikipedia.org上进行注册没有什么复杂的,但是您立即会发现自己在澡堂里待了一天。 这是它们对机器人的防护。 因此,第二天晚上,我统治了XML,很高兴看到它变得如此简单,并且在地图上出现了标志和标志。

多边形


图片

如果事实是事实,那么我们去Wikipedia,然后在Open Street Map中获取地理数据。 挑选本地副本,学习请求立交的语言,这很酷,但是我什至无法想象会花费多长时间。 而且您还需要从某个地方获取层次结构。幸运的是,一个善良的人已经为我解决了这个问题 。 该服务甚至提供用于检索信息的API。 我设法从那里下载了所有多边形,直到第6级(含)(分区)并填充了Postgres中的所有内容,然后才多出了2 Gb。 并非没有冒险-一些多边形是如此之大(例如,在压缩的GeoJSON中,加拿大的重量超过100 Mb),导致服务器崩溃或没有响应。 我不得不手动绕过这样的时刻。 我下载了所有子级并将它们合并到QGIS中。 顺便说一下,这是一个开源项目的另一个例子,对我有很大帮助。

大数据问题


因此,我有一个包含数据的数据库,我启动了游戏,然后……等待……再次等待……出现了! 我试图拖动多边形-他死了,吉姆! Chrome无法处理这么多的积分而掉下来。 前额策略不再有效,是时候考虑了。 最明显的是减少多边形的细节。 根据经验得出的公式取决于图形的面积-效果会更好。 在运行正常的计算机上,该算法可以即时运行,而服务器的资源却受到严重限制。 连接的redis,已经在服务器上变得更好。 但是,截断的多边形对于Drag'n'Drop很有好处,当设置到正确的位置时,边界与绘制Google地图的边界并不重合。 嗯,可以通过应用不太激进的公式来减少细节,从而避免这种情况。 由于已经有2个缓存,为什么不尝试缓存所有可能的缓存呢? 信息框(使用两种语言)飞到Redis,计算答案所依据的边界,多边形的中心以及站点的静态页面。 结果,游戏开始运行得更快,并且Postgres消除了很多工作量,从理论上讲这可能是瓶颈。 减号-如果没有Redis,该应用程序将无法运行。

第一次部署


现在是时候向朋友展示该项目以征求反馈了。 剩下的只有一点:生成sitemap.xml,添加robots.txt,连接指标,添加社交按钮。 网络...部署! 我选择AWS作为托管 希望能适应所提供的免费资源。 对于初学者项目,这是一个很好的堆栈:

  • 应用程序服务器(t2.micro:1xCPU,1 Gb RAM,20Gb SSD)
  • 数据库(db.t2.micro:1xCPU,1 Gb RAM,20Gb SSD)
  • 带CDN的文件存储(5 Gb S3,50 Gb流量)
  • 缓存服务器(cache.t2.micro:1xCPU,0.5 Gb RAM)
  • Elasticsearch + Kibana(t2.small.elasticsearch:1xCPU,2 Gb RAM)

这只是我设法使用的列表。 一路上,我决定以文章的形式草拟我的耙子,但很快就死了。 时间过去了,但是尚不清楚是否有人需要。

结果,在服务的那一年,我付了大约10美元,甚至是出于愚蠢。 但是,这里的试用期结束了,我不得不搬走了,因为 拥有整个经济的成本开始接近数百美元。 比较了关税,并选择了DigitalOcean。 目前,我有足够的机器配备2 Gb RAM来存储所有内容(应用程序服务器,数据库和缓存),但是我将静态数据和CDN留在了AWS上。 现在我发现DO还以每月5美元的价格提供了CDN和存储,因此考虑移动这部分也是很有意义的。

转移到开源


今年一月的傍晚,我收到了丹麦学校的来信。 其实质在于他们有100美元,他们想把它们给我。 但是有一个条件-项目的源代码必须是开放的。 在那一刻之前,我什至还没有想到过开源。 两个晚上去考虑和选择许可证。 结果,我根据GPLv3许可在Github上上传了资源,并收到了承诺的100美元。 这大大增加了动力-我的项目非常有用! 然后我冲向了下一个目标-游戏编辑器。 这样每个人都可以创建自己的难题。 例如,“参加第二次世界大战的国家”,“克拉斯诺达尔地区的区域”,“内陆国家”……但是为此,需要注册和原始的个人帐户。 结果,开发工作拖了三个月之久。 在这段时间里,我编写了一个区域树,该树将通过ajax提取数据,连接本地化,学习如何将Google地图保存为图片以生成预览并剪切Redux。 是的,他从一开始就帮助我处理数据,但现在它更有可能会干扰。 我将不得不拖动化简器以在地图上绘制多边形,以及处理其移动的代码。 幸运的是,删除与全局状态的绑定仅花费了几天,而将代码移至本地状态甚至简化了应用程序。 当然,这是一个很好的体验:)

服务连接


事实证明,许多有偿服务为开源项目免费提供其服务。 我将只列出与我自己连接的那些。

- 哨兵 。 我认为此错误捕获服务是每个人都熟悉的。 当我刚部署项目时,日志记录包括向邮件发送堆栈跟踪。 这仅适用于后端,但我也想跟踪前端的错误。 而且并非徒劳-我在短短2周内就用尽了免费消息的限制。 大多数错误都发生在Google地图库的肠道中,乍看之下很奇怪。 在调查期间,事实证明这全是我的错。 更正持续了一个多月,但这是一个非常有用的javascript错误处理实践。

- 群众 -本地化。 我计划使每个人都可以访问该项目。 其中包括以他的母语显示的信息框。 从Wikipedia填写它们不是问题,但是为了保持一致,我还希望使用相同语言的界面,到目前为止,该界面仅被翻译成俄语和英语。

图片

-CircleCI 。 没有CI / CD,测试和自动部署,任何现代项目都无法做。 我选择CircleCI的唯一原因是,当我编写用于Yandex.Disk时,我已经与TravisCI 合作 。 我觉得它更适合测试库,因为 设置代码测试环境的矩阵很容易。 但是对于测试本身,我遇到了一个问题-尽管基础架构已经准备就绪,但测试数量却不尽人意。

图片

- 工作服 。 代码覆盖率可视化服务。 还可以提供一个标签以插入README.md项目。

-SonarQube 。 用于代码质量控制的收集器。 它根据各种规则检查代码,考虑循环复杂性,通过测试监视覆盖范围,甚至识别代码重复! 一项非常有趣的服务,我还没有时间完全了解。

图片

-Github机器人。 到目前为止,仅Dependabot已连接,这会更新依赖关系。

图片

我建议在评论中分享其项目中的服务和机器人列表。

虫子


有关错误和问题的分析值得单独撰写。 有很多有趣,复杂且难以修复的功能(因此,楚科奇(Chukotka)始终站在它的位置)。 当前,有一种确实困扰着用户。 收到响应后,将删除多边形并重新创建多边形(在react-google-maps库中),并且如果此时用户拖动了多边形,则Google地图会继续假定该过程尚未完成。 似乎在拖放过程中,多边形消失了,您将无法再抓取其他任何多边形。 您当然可以在拖放过程中锁定响应处理,但这肯定会杀死多人游戏,而我目前正在努力实现该游戏。 我试图找到一种以编程方式中止拖放的方法,但最后我提出了一个关于StackOverflow的问题以及一个关于Google Maps错误,希望他们会注意它。 在此之前,他添加了一个按钮“游戏已损坏!”,该按钮可重新初始化整个地图,但不会重置结果。

接下来是什么?


  1. 设计。 我承认,一切都非常糟糕。 有必要聘请设计师和布局设计师,因为我本人不是布局和布局的朋友。
  2. 营利。 最初,我没有计划任何事情。 该项目致力于基础教育,我认为每个人都应该可以使用。 丹麦学校的一封信给我很大的启发,但是将近一年过去了,在那段时间里,只有一笔5美元的汇款。 好吧,我不相信它甚至可以为服务器付费。 但是,无论如何,他还是在Patreon上发起了一场运动 。 同时,您可能可以考虑为教师或组织引入带薪机会。 例如,我有与学习管理系统集成的经验,学习管理系统是一组平台,可让您创建课程,并且在欧洲和美国非常受欢迎。 据我了解,即使源代码也在Github上的GPL之下,但作为作者,这并不妨碍我开发并行的商业版本。
  3. 手机。 我想发布适用于iOS / Android的应用程序。 根据Yandex度量标准,四分之一的用户尝试使用手机或平板电脑进行游戏,但事实证明他们有困难。
  4. 发展。 所有工作都在GitHub上完成。 我想继续开发该项目,但是很难单独完成。 这些计划包括添加多人游戏,在Workshop中制作标签,评分和过滤器,为物理地图(山脉,海洋,半岛)添加多边形。 仍然有很多有趣的事情,因此本文的目标之一是找到志趣相投的人。 另一种选择是去基金会,例如Python Software Foundation并获得资助。

这是目前的状况。 感谢您阅读到底! 您可以在此处播放geopuzzle.org ,并查看GitHub上的源代码。

不明飞行物护理分钟


这些材料可能会引起矛盾的感觉,因此在写评论之前,请刷新您记忆中的重要内容:

如何发表评论并生存
  • 不要发表令人反感的评论,不要发表个人看法。
  • 避免使用淫秽的语言和有害行为(即使是隐蔽的形式)。
  • 要报告违反网站规则的评论,请使用“报告”按钮(如果有)或反馈表单

如果发生以下情况该怎么办? 被封锁的帐户

哈勃( Habr)哈伯雷特(habraetiket) 作者代码
完整版的网站规则

Source: https://habr.com/ru/post/zh-CN427209/


All Articles