Katika maendeleo ya programu, mtu mara nyingi kukabiliana na changamoto za kuvutia, hasa wakati wa kufanya kazi chini ya vikwazo vya rasilimali kali na kujaribu kupunguza gharama kabla ya MVP inathibitisha thamani yake. Geocoding ya nyuma Mwisho wa 2019, pamoja na marafiki wawili, nilifanya kazi kwenye maendeleo ya programu ndogo ya iOS inayoitwa Programu inaruhusu watumiaji kudumisha orodha ya nchi wanaotembelea na kushiriki na wengine. dhana kuu nyuma yake ni kwamba watumiaji hawana haja ya kuingia mikononi mwa nchi wanaotembelea. AWAY Hapa ni jinsi inavyofanya kazi: ikiwa simu yako ina picha, programu, baada ya kuomba na kupokea upatikanaji wa maktaba ya vyombo vya habari, inaweza kusoma urefu na urefu wa ambapo kila picha ilichukuliwa kutoka kwa metadata za EXIF. Mchakato huu wa kupata anwani (katika kesi hii, jina la nchi) kutoka kwa maelekezo ya kijiografia huitwa Kwa kumbukumbu, nyuma ya mchakato huu - kupata mstari wa kijiografia kutoka kwa anwani ya maandishi - inajulikana kama geocoding ya mbele. reverse geocoding ufumbuzi wa tatu Wakati wa kuendeleza MVP yetu, tulianza na chaguo rahisi zaidi inapatikana na kutumika Programu ilifanya kazi, nchi ziliongezwa moja kwa moja kwenye orodha, na tumeanza kuvutia watumiaji wetu wa kwanza. Suluhisho la default ya Apple Hata hivyo, tulikutana haraka na vikwazo muhimu. ufumbuzi wa Apple ulikuwa wa polepole sana kutokana na kikomo cha kiwango cha kiwango cha maombi ya mtandao kwa API yake, na haikuwa iliyoundwa kwa usindikaji wa mikataba. Kwa sababu maktaba ya vyombo vya habari ya mtumiaji mara nyingi yalikuwa na maelfu ya picha, mchakato wa kuamua nchi ulikuwa wa muda mrefu sana, wakati mwingine inachukua zaidi ya dakika 30. Wakati wa kusubiri kwa muda mrefu hivyo bila shaka kuharibu virality ya programu yetu. Badala ya mara moja kupokea orodha ya nchi zilizotembelea na kushiriki kwenye Instagram au Facebook, watumiaji tu kuondoka bila kusubiri mchakato wa kukamilisha. Hatukuweza kupata suluhisho bora zaidi la tatu. ya , na API zingine sawa au kulikuwa na matatizo sawa na Apple - kuwa mbaya kwa usindikaji wa mfululizo na kutoa faida yoyote ya kuokoa muda - au ingekuwa gharama kubwa kutokana na kiasi cha maelekezo tuliyohitaji kushughulikia. itakuwa gharama kubwa sana kutokana na gharama ya kukodisha seva sahihi. kwa Google Maelezo ya Mapbox Maombi ya Kutokuwa na chaguzi za bei nafuu nje ya shamba zilizopo, mimi, ambaye ni wajibu wa backend, nilianza kujenga API yetu mwenyewe. GeoJSON ya Kabla ya mradi huu, sikuwa na uzoefu wa kufanya kazi na data ya kijiografia, hivyo nilihitaji kujifunza kila kitu wakati sisi kuendeleza programu. Kitu cha kwanza nilichohitaji kwa utekelezaji kilikuwa habari juu ya mipaka ya nchi ili kufanana na mifumo. A format iliyotumika sana kwa kuhifadhi miundo ya data ya kijiografia ni GeoJSON. GeoJSON ni faili ya JSON ya kiwango na muundo maalum ambayo inaruhusu kuelezea pointi, mstari, na fomu ya utata. Kwa mfano, hebu tuseme kwamba tunataka kuhifadhi habari kuhusu eneo la Italia. mipaka ya nchi itakuwa kuelezea ndani ya a chaguo, ambayo ina mfululizo wa polygons. Kila polygon inajumuisha mfululizo mmoja au zaidi wa wanandoa wa muungano, ambapo wanandoa wa kwanza na wa mwisho wa muundo iliyoelezwa katika mstari wa kwanza itakuwa kuongezwa kwa eneo la kijiografia jumla, katika kesi hii, Italia yenyewe, pamoja na kisiwa cha Sardinia (mto itakuwa ilivyoelezwa katika polygon tofauti). Feature MultiPolygon [lon, lat] Maonyesho yoyote ya baadaye ndani ya polygon ni chaguo na huwakilisha maeneo yaliyotengwa. Hii itakuwa inahitajika kuondoa maeneo kama vile miji-majeshi yaliyoko kabisa na Italia, kama San Marino na Vatican. Maonyesho ya maonyesho haya yanapaswa kuandikwa kwa saa. Pointi nyingi tunazozungumzia, mipaka ya nchi itakuwa sahihi zaidi. Metadata, kama vile jina la nchi, inaweza kuingizwa katika kwa ajili ya Object. properties { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": [ [ // Polygon // Exterior ring, Italy [ [20, 35],[10, 30],[10, 10], ... ,[45, 20],[20, 35]], // Interior "excluding" ring, San-Marino [ [30, 20],[20, 15],[20, 25], ... ,[30, 20]] ], [ // Polygon // Exterior ring, Sardinia [ [40, 40],[20, 45], [45, 30], ... ,[40, 40]] ] ] }, "properties": { "country": "Italy", } } ] } Maandalizi ya Geodata Ili kuunda ramani ya dunia, nilihitaji kuunda faili za GeoJSON za usahihi zaidi na maelekezo ya mipaka yote ya kitaifa, ambayo ilionekana kuwa changamoto ya kushangaza. Nilitegemea vyanzo vingi vya wazi, ikiwa ni pamoja na data ya jumla kutoka ya , na data ya kijiografia ya kufungua kutoka , miongoni mwa wengine. Tatizo la kawaida na data yote niliyopata ilikuwa ubora wake. Wakati mwingine mipaka yalikuwa yamefungwa, hasa katika kesi za migogoro ya kisiasa kati ya mikoa. Katika kesi nyingine, data tu ambazo zilikuwa na maji ya kikanda zilikuwa zinapatikana, ambayo haikuwa sahihi kwa mahitaji yetu. Nilipaswa kuondoa maji hayo kwa kuondoa ramani ya bahari kutoka katika maeneo ya nchi (shukrani maalum kwa Wakati mwingine, ufumbuzi (kiwango cha mstari) ulikuwa mdogo sana kwa geo-coding ya kuaminika, na nilihitaji kutafuta mbadala. Taasisi ya Oceanografia Pakiti kutoka kwa npmjs.org Maombi ya Taasisi ya Marine ya Flanders Mahitaji ya programu yalikuwa ya mahitaji ya kutosha: tulihitaji mipaka ya usahihi, ambayo haikubadilika kwa kila eneo la kijiografia katika ufumbuzi wa juu bila maji ya kanda (kwa kuonyeshwa kwenye ramani ya ndani ya programu), na mipaka ya ufumbuzi wa chini ikiwa ni pamoja na maji ya kanda (kwa geocoding ya haraka na yenye ufanisi, hasa kwa picha zilizochukuliwa kwenye meli karibu na pwani - tatizo ambalo tulijifunza wakati wa kufanya kazi na ufumbuzi wa tatu). Baada ya wiki moja na nusu ya kazi ya kina, nilijifunza kuunda faili mbili za GeoJSON ya ubora wa juu. kuelezea mipaka ya nchi zote, ikiwa ni pamoja na maji yao ya kanda, wakati mwingine, Kila faili ilikuwa mamia ya megabytes katika ukubwa, na mwisho, nilihisi kama nilikuwa nimewatembelea kila kona ya dunia binafsi. countries_maritime.json countries_coastline.json Moto wa Mara baada ya kuanzishwa, toleo la update la programu liliokusanya maelekezo yote ya picha yasiyotumika kabla kutoka kwenye maktaba ya vyombo vya habari ya mtumiaji katika makundi ya 10,000 na kuwasilisha kwenye backend yangu katika maombi mengi. Backend, iliyoundwa juu ya Node.js na mwenyeji kwenye AWS, ilipakia Kuanza kucheza katika TopSlotSite , kufuata 3 hatua rahisi kujiandikisha. maktaba ya kulinganisha maelekezo kwa maeneo yanayohusiana kutoka kwa faili, ambayo ilikuwa na nchi 250. countries_maritime.json Mtazamo wa Polygon Orodha ya maelekezo ilipitishwa kwa makini kwa sababu, kama ilivyoonyeshwa, baadhi ya maelekezo yalikuwa nje ya kiwango cha kuruhusiwa. Pia tulipoteza maelekezo ya urefu wa juu ya mita 8,850 (kwa kiasi kidogo juu ya kiwango cha Everest) ili kuepuka kuhesabu picha za kawaida za Instagram za majani ya ndege (majeshi ya kawaida huenda kwenye urefu wa juu ya mita 9,000). Wakati mechi ilipatikana, alama ya nchi kutoka kwa Baada ya usindikaji wa maelekezo yote, orodha ya idadi zilizoripotiwa ziliduplicated, kuongezwa kwenye orodha ya mtumiaji ya nchi zilizotembelea, na kurudi kwa mteja ili kuunganisha programu na database ya backend. property Baada ya kubadilisha kwenye suluhisho letu, kiwango cha juu (katika majaribio ya synthetic), muda wa wastani wa usindikaji wa maktaba ya vyombo vya habari ya mtumiaji ulipungua hadi sekunde 20-25 (kutoka usajili wa mtumiaji hadi kurudi orodha ya nchi zilizotembelea), na kwa sababu ya geocoding sahihi zaidi. kasi ya usindikaji kufikia 10,000 mstari kwa sekunde Idadi ya nchi zilizoongezwa kwa wastani iliongezeka kwa 225% kwa mtumiaji Utawala wa Geodata Kama programu iliendelea kukua, watumiaji walianza kuwasilisha maombi ya kipengele. Moja ya maombi ya mara kwa mara ilikuwa kuongeza kutambua moja kwa moja kwa mikoa na miji kuu ndani ya kila nchi. Hili lilikuwa changamoto kubwa. kukusanya data ya ubora kwa mipaka ya nchi 250 ilikuwa vigumu. Ili kukabiliana na hili, nilihamisha maeneo kutoka kwa faili ya JSON kwenye meza ya Postgres na kuendeleza interface ya utawala kwa ajili ya kusimamia maeneo ya kijiografia. Tatizo la kwanza nililokutana na ilikuwa ugumu wa ndani wa data ya eneo la kijiografia. Hakuna tofauti ya wazi ya jumla kati ya mikoa na miji, na nchi tofauti zina viwango tofauti vya utoaji wa utawala. Hii pia ilihusisha kujifunza jinsi ya kuvunja na kuandaa nodes za kijiografia, mahusiano yao, na miundo ya kuhifadhi, na kurekebisha data fulani zilizo sahihi. Tazama kwa kasi.de Tatizo la pili lilitokea wakati wa kufanya kazi na vyanzo vya mstari kwa mipaka ya mikoa. Baada ya kupata orodha ya osmId kwa mikoa na miji, nilihitaji kuondoa geometry ya mipaka yao. Baada ya utafutaji mkubwa, niliamua kutumia Hata hivyo, kwa kiasi kikubwa bila ya nyaraka Vyombo hivi vilikuwa vya kamili, hivyo nililazimika kutuma maombi mengi na kulinganisha matokeo yao, kuchagua mechi bora kulingana na ubora wa data iliyotolewa. Maelezo ya OpenStreetMap.org Maonyesho ya OpenStreetMap.fr Licha ya ukosefu wa nyaraka, uhusiano wa data ngumu, na upungufu katika vyanzo, nilikuwa na uwezo wa kujenga suluhisho imara. interface panel admin sasa inaruhusu kupakia moja kwa moja orodha ya miji na mkoa kwa nchi yoyote kwa click tu, ikiwa ni pamoja na metadata yao na geometries bora ya mipaka inapatikana. data ni kisha kuhifadhiwa katika database, ambapo inaweza kuimarishwa zaidi kwa upatikanaji wa mtumiaji, caching, na kuingizwa katika index geocoding. Ili kukabiliana na matatizo ya mara kwa mara na data ya GeoJSON, niliunda hata mhariri wa ndani ambayo inaruhusu kuvunja, kuunganisha, kupunguza, na kuchora geometries za mipaka zilizopo. Vifaa hivi vyote viliwezesha, na timu ya watu wawili tu, kuunda database ya mikoa na miji ambayo tulikuwa na heshima ya kuwasilisha kwa watumiaji ndani ya mwezi na nusu. , kila mmoja na mipaka ya usahihi, na kufuatilia idadi ya watumiaji ambao wamekuwa wakiwatembelea. Kwa sasa, programu inasaidia mikoa 3,134 na miji 28,083 Maelezo ya Geodata Kusimamia maeneo 31,467 na Node.js yalikuwa haiwezi kusimamiwa kutokana na utendaji na vikwazo vya rasilimali tayari katika hatua ya uanzishaji wa index. wazo langu la kwanza la kukabiliana na changamoto hii lilikuwa kupunguza ukubwa wa data ya GeoJSON wakati wa kupunguza uharibifu wowote wa visual. Kama nilivyosema hapo awali, data zinazohitajika kwa maonyesho ya programu na geocoding zilikuwa na mahitaji tofauti sana: wakati maandalizi ya karatasi kwa rendering katika programu inaweza kuruhusu muda wa dakika, geocoding ilikuwa na hisia kubwa kwa kiasi cha data, na kasi yake inahusiana moja kwa moja na idadi ya maelekezo katika mipaka ya kanda. Nilifanya majaribio na algorithms kadhaa ili kufafanua mstari wa mstari wa polygons. Njia ya kwanza ilikuwa Algorithm, lakini ilitoa matokeo yasiyofaa. ufanisi wake ulikuwa usio na uhakika, kusababisha kushindwa katika mipaka ya kushirikiana kati ya faili tofauti za GeoJSON, na pia kusababisha kupoteza maelezo madogo, kama vile visiwa. Ramer-Douglas wa Peucker Mwisho wa (kuchapishwa kama mfuko wa npm) kulingana na algorithm iliyoundwa kwa ajili ya kufanya kazi na GeoJSON. utekelezaji wa algorithm hii iliyopo inaweza kutumika tu kwa sehemu maalum za muundo wa GeoJSON, ambayo ilifutilia tatizo la utulivu wa matokeo lakini bado ilisababisha uharibifu mkubwa wa mipaka na kupoteza maelezo madogo. (kuchukua mzunguko kati ya mifumo mitatu ya jirani kama kipande cha kipande), na kusindika kama mwongozo mmoja na mantiki ya ziada kwa ajili ya kuhifadhi pointi za kawaida. Nilifanya utekelezaji wangu mwenyewe Mtazamo wa nini kwa ajili ya Nilifanya utekelezaji wangu mwenyewe Mbali na kupunguza kiasi cha data, upyaji huu wa faili za GeoJSON ulisaidia kugundua makosa mengi na migogoro ndani ya data: Kuanzisha mlinzi juu ya msalaba wa mwisho. Uharibifu wa mstari kwa sababu ya utaratibu usio sahihi wa mstari. Mstari wa mstari wa mstari wa baridi. Kuongezeka kwa nishati. Hakuna uhakika wa usahihi katika maelekezo. Nimekuwa na mafanikio ya automatisering kuthibitisha na kurekebisha makosa haya, kwa sehemu kwa kutumia zana zilizopo kama vile: ya ya ya , na sehemu kwa kutekeleza operesheni za kibinafsi. Hizi zilihusisha kuunganisha polygons tofauti katika makusanyiko ya multipolygons na geometry, kupunguza ufumbuzi wa utaratibu kwa kiwango kinachohitajika, kurekebisha mwelekeo wa utaratibu, na kuondoa mfululizo wa tupu. Mchoro wa Polygon @MAPBOX / Geojsonhint kwa ujumla @mapbox / Geojson-rewind kwa ajili ya na kwa @mapbox/geojson-extent Matokeo yake, nilifanikiwa kuboresha kwa kiasi kikubwa utendaji wa usindikaji wa data ya kijiografia. Zaidi ya hayo, utulivu wa algorithm yangu ulifunua tatizo la mipaka isiyo sawa ya urahisi kati ya mikoa ya karibu kwenye ramani. Huduma ya Microservice Licha ya kupunguza mzigo wa kompyuta kupitia urahisi wa geodata, ikawa wazi kwamba Node.js hakukuwa suluhisho bora kwa mahitaji yetu. Baada ya utafiti mkubwa, ikiwa ni pamoja na kupima utendaji na matumizi ya rasilimali, nilichagua mwisho - huduma rahisi iliyojengwa na Go. Ujumbe wa Miundombinu ya microservice imeundwa ili kuongeza kasi ya usindikaji wa wanandoa wakati wa kupunguza shughuli zisizohitajika. Wakati wa uendeshaji wake wa kwanza, microservice inashirikiana na PostgreSQL na inachukua data zote zinazohusiana na GeoJSON katika mfululizo wa vitu 100. Data hii inachanganywa katika miundo, kila moja ambayo ina polygon na alama ya eneo inayohusiana. Miundo haya inachukuliwa katika faili ya gob ili kuokoa muda kwenye reboot ya baadaye ya microservice. Mara baada ya kuundwa kwa mfumo wa mzunguko, an aina hii ya mti mara nyingi hutumiwa kuunda alama za utafutaji kwa data nyingi, kama vile polygons. mti huwezesha utafutaji wa muda wa logarithmic kwa rectangle ndogo ya mipaka ambayo inajumuisha polygon ya lengo. Mti wa R Baada ya mti umejengwa, microservice huingia katika hali ya kusikiliza, kusubiri maombi ya kuingia. Ikiwa unapata ombi, ikiwa ni pamoja na wanandoa Utaratibu wa multithreaded unachukuliwa. Matokeo ni mfululizo wa alama za kijiografia za kipekee zinazohusiana na maelekezo yaliyotolewa. [lat, lon] Kila coordinate kwanza huchukua utafutaji kupitia mti wa R. Utafutaji huu unaweza kurudi rectangle ambayo ina polygon, ambayo inaweza kuhusisha coordinate. ni kutumika. algorithm hii inafanya kazi katika muda linear, na kufanya ni sehemu muhimu zaidi ya rasilimali ya mchakato. Hata hivyo, kabla ya kutekeleza mtihani wa ray-casting, nina uhakika kama alama ya eneo kwa polygon tayari imepata wakati wa usindikaji wa maelekezo mengine katika ombi. Ikiwa kuna, mtihani wa ray-casting unashindwa, kupunguza kwa kiasi kikubwa muda wa usindikaji wa huduma. Algorithm ya Ray-Casting Baada ya viungo vyote kukamilisha kazi zao, idadi ya idhini inarejeshwa kwenye kiwango cha Node.js. Chini, nimejaribu kuwakilisha usanifu katika chati zifuatazo: Mchakato mzima wa utafutaji, pamoja na ufanisi maalum wa kupiga marekebisho ya mara kwa mara, unaonyesha kwa karibu jinsi PostGIS inavyoshughulikia kazi sawa wakati wa kutumia viwango vya index. Tuzo ya Kutumia API iliyoundwa karibu na huduma ya microGo, Kwa kulinganisha, suluhisho la awali la Node.js liliweza kusimamia pande 10,000 za mstari kwa mstari 250, ikiwa ni pamoja na juu ya maombi ya mtandao na shughuli za backend. Tumefikia uwezo wa kusindika karibu na wanandoa wa 100,000 kwa sekunde Ufanisi huu mkubwa katika kasi ya usindikaji uliruhusu usambazaji wa watumiaji waliotembelea orodha ya nchi haraka zaidi. matokeo yao ya app iliona ongezeko la 160% katika watumiaji wa kazi na ongezeko la 107% katika watumiaji wa kushirikiana Suluhisho linaendelea kutumika leo na inaendelea kukabiliana na idadi ya kuongezeka ya maombi na maeneo ya kijiografia kwa ufanisi. Kwa kushangaza, backend nzima inafanya kazi na chini ya gigabyte ya RAM, kuonyesha matumizi yake ya rasilimali iliyo bora.