
Saya ingin berbicara tentang proyek yang telah berkembang selama beberapa tahun terakhir. Ini disebut
GeoPuzzle dan merupakan permainan puzzle di peta politik dunia. Tujuannya adalah untuk menempatkan potongan-potongan negara di tempatnya. Gagasan itu terlihat dalam artikel
"Puzzle Mercator untuk Geografi Profesional" , juga memainkan tetris dari negara-negara (masih di bawah DOS) di masa kanak-kanak, tetapi saya tidak ingat nama programnya. Saya sangat terinspirasi oleh gagasan bahwa saya ingin membuat produk yang lengkap, menarik tidak hanya untuk anak sekolah, tetapi juga untuk para ahli geografi. Pengembangan proyek dapat diamati di
GitHub .
Prototipe
Artikel "Puzzle Mercator untuk ahli geografi" diterbitkan pada 8 Februari 2013, tetapi setelah 4 bulan saya memiliki prototipe siap, di mana poligon dari semua negara di dunia berkumpul. Beberapa saat kemudian, saya menambahkan wilayah Rusia dan negara bagian AS dan membuat pilihan posisi awal di peta untuk poligon acak. Saya menggambarkan proses pengembangan
di blog saya , memposting kode sumber di
GitHub . Dan itu - terjebak. Saya mendapat waktu luang yang jauh lebih sedikit, motivasi saya hilang (tidak ada keputusan), dan kompleksitasnya meningkat secara eksponensial. Itu adalah proyek hewan peliharaan, dan tugas utamanya adalah mempelajari sesuatu yang baru, jadi saya agak sesat dengan teknologi. Pada klien, tentu saja, javascript (dengan mana saya tidak banyak bekerja saat itu), skrip ruby ββ(sekali lagi, bahasa baru bagi saya) bertanggung jawab untuk persiapan data, tetapi pada server ada erlang (saya ingin mencoba sesuatu yang murni fungsional). Keluar sepenuhnya dari zona nyaman: sulit untuk bekerja secara langsung dengan benda-benda PostGIS, rasa sakit mengubah string ke erlang, mengonfigurasi YAWS adalah masalah yang terpisah sama sekali ... Pada tahap berikutnya, saya menyadari bahwa saya tidak bisa mengatasi semua kebun binatang ini untuk membuat produk lengkap, dan pergi berpikir selama beberapa tahun.
GeoPuzzle

Situs ini telah berfungsi selama ini, orang-orang bahkan pergi ke sana, tetapi saya benar-benar ingin menambahkan satu detail lagi: untuk menampilkan setidaknya beberapa informasi tentang poligon yang baru ditemukan. Karena itu, saya berencana untuk menghabiskan liburan Tahun Baru di tahun 2017 dengan manfaat. Karena masalah dalam prototipe, saya memutuskan untuk menulis ulang semuanya dan membuat produk pada sesuatu yang akrab - Django. Di luar kotak ada beberapa hal yang sangat menyederhanakan hidup saya, misalnya, panel admin dan bekerja dengan PostGIS melalui ORM. Tetapi sebagai permulaan, itu perlu untuk menciptakan kembali fungsi yang sudah berfungsi. Hanya butuh beberapa malam, dan sebagian besar waktu diambil dengan memuat data dari file KML. Tidak terlalu banyak proses impor itu sendiri sebagai persiapan dan pemulihan pengetahuan saya tentang cara bekerja dengan mereka. Ngomong-ngomong, saya mengambil
poligon dari
gadm.org pada waktu itu. Ini bekerja dengan baik untuk negara-negara, tetapi ada masalah tertentu dengan keakuratan wilayah, jadi saya mengambil waktu tunggu untuk masalah ini.
Beberapa kata tentang level administratif di geodata (level).Semua negara dibagi menjadi banyak wilayah, yang dibagi menjadi bagian yang lebih kecil lagi. Secara total, ada 12 lapisan dalam hierarki seperti itu.
Misalnya, untuk Rusia:
- Rusia (2) -> Distrik Federal Selatan (3) -> Wilayah Krasnodar (4) -> Distrik Vyselkovsky (6) -> Seni. Desa (8)
- Rusia (2) -> Distrik Federal Selatan (3) -> Wilayah Krasnodar (4) -> Krasnodar (6) -> Distrik Prikubansky (9) -> Kopanskaya (10)
- Prancis (2) -> Metropolis Perancis (3) -> wilayah Normandia (4) -> departemen Orne (6) -> kanton Donfron (7) -> kotamadya Donfron-en-Poiret (8) -> Donfron (9)
Unit teritorial di berbagai negara dipanggil dengan caranya sendiri, tetapi untuk saya sendiri, saya menyimpulkan divisi ini: Negara (2) -> Wilayah (4) -> Distrik (6). Pembagian administratif selanjutnya dibiarkan nanti.
Pengembangan proyek
Saat itu, aplikasi itu hanya kumpulan halaman HTML dengan minimal CSS. Saya ingin cepat memeriksa idenya, dan tidak repot dengan desain. Gagasan itu ternyata dapat diwujudkan, dan inilah saatnya untuk membuat cangkang yang indah untuk itu. Karena Saya tidak memiliki rasa keindahan di UI, lalu Bootstrap untuk membantu saya. Tidak ada antarmuka, tetapi muncul, dan bahkan disesuaikan untuk perangkat seluler. Tapi ini hanya langkah pertama dalam menata frontend.
Bagaimana rasanya belajar JavaScript pada tahun 2016 ?! Ketika kode tersebut dikompilasi ke dalam dialek lain, ia dibuat templated, direkatkan bersama sehingga nantinya bisa dipotong-potong. Saya, sebagai backend, takut, tetapi kompleksitas bagian klien direncanakan cukup besar, yang mensyaratkan perlunya menggunakan kerangka kerja atau perpustakaan. Saya memutuskan untuk Bereaksi karena dua alasan: Saya tidak membutuhkan SPA, tetapi serangkaian komponen untuk halaman yang berbeda, dan saya ingin segera melihat hasilnya. Tetapi sebelum Anda memulai pemrograman, Anda harus mengatur lingkungan. Sekarang saya mengerti front-end yang akrab, yang mengatakan bahwa dia mengatur Webpack selama 2 hari. Ternyata itu bukan lelucon.
Pada saat itu, saya menyerah pada persuasi dan menerapkan logika aplikasi menggunakan Redux. Mungkin ini bukan kesalahan, karena diizinkan untuk memasukkan topik dengan cepat. Aturan formal memungkinkan saya untuk menulis kode dan memastikan bahwa kode itu berfungsi tanpa melihat di bawah tenda. Redux menggunakan middleware-nya mengabstraksi saya dari interaksi jaringan, yang memungkinkan saya untuk memeriksa respons ke server. Ya, hingga saat ini, klien bekerja sendiri - permintaan ajax mengeluarkan semua data yang diperlukan dan memeriksa jawabannya sendiri. Pengguna bisa menipu dengan melihat data yang berasal dari server. Selain itu, saat memuat, data terbang, diperlukan hanya setelah jawaban yang benar. Setelah menerapkan verifikasi melalui soket web, prosesnya menjadi lebih tepat secara ideologis - jawabannya memverifikasi kode yang tidak tersedia untuk klien. Untuk pengguna, ini masih tampak langsung: mengirim titik-titik ekstrim poligon ke server, memeriksa apakah mereka memasuki kotak dengan kesalahan, mengemas data untuk kotak info dan poligon terperinci di json dan mentransfernya ke klien - masuk ke ~ 200ms.

Setelah mempelajari semua kekuatan javascript, sulit untuk berhenti. Segera ada ide di mana untuk menambahkan animasi, blok lipat, berkedip, dan versi baru gim. Salah satunya adalah "Kuis", di mana Anda harus menebak negara dengan nama, bendera, lambang atau modal. Benar, selama proses pengujian ternyata beberapa daerah tidak memiliki bendera, sementara yang lain tidak memiliki modal, sehingga beberapa negara harus disembunyikan dari daftar yang tersedia. Pada saat yang sama, mode permainan muncul di peta fisik dunia - tanpa batas negara, untuk pro nyata.
Buka sumber data
Ada ~ 50.000 poligon dalam gim ini sekarang, dan saya ingin mengucapkan terima kasih banyak kepada proyek-proyek hebat seperti Wikipedia dan Open Street Map, yang tanpanya mengisi pangkalan tidak akan mungkin. Persyaratan mendasar adalah untuk menerima dan memperbarui data dari sumber terbuka, yaitu, tanpa pengeditan manual, karena Saya tidak ingin melakukan logika sinkronisasi yang rumit. Akibatnya, saya mendapat 2 skrip yang dapat memperbarui kotak info dan poligon.
Wikipedia dan SPARQL

Apa basis data negara dan wilayah terbesar? Wikipedia! Awalnya, saya ingin menunjukkan kepada pengguna seluruh kotak info, tetapi segera meninggalkan gagasan ini. Ya, ada hal-hal penting seperti nama, bendera, ibukota, dan hal-hal lain, tetapi ada juga banyak sampah (kode telepon, bentuk pemerintahan, PDB ...). Saya mencoba mengurai yang sudah dikumpulkan, tetapi menemukan bahwa mereka memiliki struktur yang berbeda. Ini ternyata menjadi bencana: biaya tenaga kerja untuk implementasi meningkat berkali-kali lipat. Sudah waktunya untuk berhenti dan berpikir. Keesokan harinya saya belajar tentang keberadaan bahasa permintaan khusus - SPARQL. Secara tampilan, ini menyerupai SQL - juga deklaratif, dengan kata kunci
SELECT
,
WHERE
,
ORDER BY
, tetapi bekerja dengan cara yang sangat berbeda. Contoh kecil yang mengembalikan daftar negara bagian dengan ibukotanya dalam bahasa Inggris dan Rusia:
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
Terlihat liar, bukan ?! Periksa di
sini . Saya bahkan menulis
catatan kecil
di blog saya untuk entah bagaimana menyusun pengalaman saya dan membantu masuk ke topik, karena ada beberapa materi terperinci di Internet. Anda dapat belajar membaca permintaan semacam itu dengan cukup cepat, tetapi saya menghabiskan akhir pekan untuk menulis sesuatu yang bermakna. Banyak "keajaiban" dari
wd:Q3624078
dan atribut lainnya. Anda perlu tahu bahwa
wdt:P31
adalah "entitas", dan
wd:Q3624078
adalah "negara berdaulat". Orang-orang yang tidak dikenal mulai dengan tanda tanya, dan pemenuhan permintaan itu terdiri dari pencarian tiga kali lipat fakta yang akan memenuhi syarat. Misalnya
?country wdt:P31 wd:Q3024240
-" temukan semua benda yang merupakan keadaan historis "; dan kemudian objek yang sama berpartisipasi dalam tiga kali lipat lainnya
?country wdt:P36/rdfs:label ?capital
- dari mana modal
?country wdt:P36/rdfs:label ?capital
.
Sekitar seminggu kemudian, saya memiliki skrip versi pertama yang siap, yang mengunduh informasi regional dari Wikipedia. Dan kemudian masalah lain menjadi jelas - kali ini dengan data. Beberapa svg tidak memulai dengan
<?xml version="1.0" encoding="UTF-8"?>
Dan tidak dikenali oleh browser sebagai gambar yang valid. Untungnya, file sumber dapat diedit. Tidak ada yang rumit dalam mendaftar di wikipedia.org, tetapi Anda segera menemukan diri Anda di pemandian selama sehari. Inilah perlindungan mereka terhadap robot. Jadi malam berikutnya saya memerintah XML dan senang betapa sederhana itu ternyata, dan bendera dan lambang muncul di peta.
Poligon

Jika untuk fakta kita pergi ke Wikipedia, maka untuk geodata - di Open Street Map. Akan lebih baik untuk mengambil salinan lokal, mempelajari bahasa permintaan
overpass , tetapi saya bahkan tidak bisa membayangkan berapa lama waktu yang dibutuhkan. Dan Anda juga perlu mengambil hierarki dari suatu tempat ... Untungnya, satu orang baik telah
menyelesaikan masalah ini untuk saya . Layanan ini bahkan menyediakan API untuk mengambil informasi. Saya berhasil mengunduh dari sana semua poligon hingga level 6 inklusif (distrik) dan mengisi semuanya di Postgres, sedikit lebih dari 2 Gb keluar. Itu bukan tanpa petualangan - beberapa poligon sangat besar (misalnya, Kanada memiliki berat lebih dari 100 Mb di GeoJSON yang di-zip) sehingga servernya mogok atau tidak merespons. Saya harus memotong momen seperti itu secara manual. Saya mengunduh semua anak dan menggabungkannya ke QGIS. Omong-omong, ini adalah contoh lain dari proyek open source yang telah banyak membantu saya.
Masalah Big Data
Jadi, saya punya database dengan data, saya meluncurkan game dan ... dan tunggu ... lagi saya tunggu ... muncul! Saya mencoba menyeret poligon - Dia sudah mati, Jim! Chrome tidak bisa menangani volume poin sebanyak itu dan jatuh. Strategi dahi tidak lagi berfungsi, saatnya untuk berpikir. Yang paling jelas adalah mengurangi detail poligon. Secara empiris diturunkan formula yang tergantung pada area gambar - itu menjadi lebih baik. Pada komputer yang berfungsi, algoritme berfungsi dengan cepat, sementara server sangat terbatas sumber dayanya. Redis terhubung, menjadi lebih baik sudah di server. Tapi terpotong poligon baik untuk Drag'n'Drop, dan ketika diatur ke tempat yang tepat, perbatasan tidak sesuai dengan yang menggambar peta Google. Nah, ini bisa dielakkan dengan menerapkan formula yang tidak terlalu agresif untuk mengurangi detail. Karena sudah ada 2 cache, mengapa tidak mencoba untuk cache semua yang mungkin sama sekali ?! Kotak info (dalam dua bahasa) terbang ke Redis, perbatasan tempat jawaban dihitung, pusat poligon, serta halaman statis situs. Akibatnya, permainan mulai bekerja lebih cepat, dan banyak beban kerja dihapus dari Postgres, yang secara teoritis bisa menjadi penghambat. Minus - aplikasi tidak bekerja tanpa Redis sama sekali.
Penempatan pertama
Jadi sudah waktunya untuk menunjukkan proyek kepada teman-teman untuk mendapat umpan balik. Hanya sedikit yang tersisa: hasilkan sitemap.xml, tambahkan robots.txt, hubungkan metrik, tambahkan tombol sosial. jaringan dan ... sebarkan! Saya memilih AWS sebagai hosting, sebagai berharap dapat masuk ke dalam sumber daya gratis yang disediakan. Dan ini adalah tumpukan yang sangat bagus untuk proyek pemula:
- server aplikasi (t2.micro: 1xCPU, 1 Gb RAM, 20Gb SSD)
- basis data (db.t2.micro: 1xCPU, 1 Gb RAM, 20Gb SSD)
- penyimpanan file dengan CDN (5 Gb S3, 50 Gb lalu lintas)
- server caching (cache.t2.micro: 1xCPU, 0,5 Gb RAM)
- Elasticsearch + Kibana (t2.small.elasticsearch: 1xCPU, 2 Gb RAM)
Ini hanya daftar apa yang berhasil saya gunakan. Sepanjang jalan, saya memutuskan untuk menyusun rake saya
dalam bentuk artikel , tetapi dengan cepat mati. Waktu berlalu dengan sopan, tetapi tidak jelas apakah ada yang membutuhkannya.
Sebagai hasilnya, untuk tahun pengabdian saya membayar sesuatu dengan urutan $ 10, dan bahkan itu karena kebodohan. Tetapi di sini masa percobaan berakhir, dan saya harus pindah, karena biaya kepemilikan seluruh ekonomi ini mulai mendekati beberapa ratus dolar. Tarif yang dibandingkan, dan diselesaikan di DigitalOcean. Untuk saat ini, saya memiliki mesin yang cukup dengan RAM 2 Gb untuk semuanya (server aplikasi, database, dan cache), tetapi saya meninggalkan statika dan CDN di AWS. Sekarang saya mengetahui bahwa DO juga mendapatkan CDN dan penyimpanan seharga $ 5 / bln, jadi masuk akal untuk berpikir tentang memindahkan bagian ini juga.
Transfer ke Sumber Terbuka
Malam Januari ini saya menerima surat dari sekolah Denmark. Esensinya berasal dari fakta bahwa mereka memiliki $ 100, dan mereka ingin memberikannya kepada saya. Tetapi ada syarat - kode sumber proyek harus terbuka. Sampai saat itu, saya bahkan belum memikirkan Open Source. Beberapa malam pergi untuk memikirkan dan memilih lisensi. Akibatnya, saya
mengunggah sumber di Github di bawah lisensi GPLv3 dan menerima $ 100 yang dijanjikan. Ini sangat meningkatkan motivasi - proyek saya sangat berguna! Dan saya bergegas ke tujuan berikutnya - editor game. Sehingga setiap orang bisa membuat puzzle sendiri. Misalnya, "Negara-negara yang berpartisipasi dalam Perang Dunia Kedua", "Distrik Wilayah Krasnodar", "Negara-Negara yang Terkurung Darat" ... Tetapi untuk ini, pendaftaran dan akun pribadi primitif diperlukan. Akibatnya, pengembangan berlangsung selama 3 bulan. Selama waktu ini, saya menulis sebuh pohon wilayah yang akan menarik data melalui ajax, menghubungkan pelokalan, mempelajari cara menyimpan peta Google sebagai gambar untuk menghasilkan pratinjau dan memotong redux. Ya, dia membantu saya menangani data di awal, tetapi sekarang lebih cenderung untuk ikut campur. Saya harus menyeret reduksi untuk menggambar poligon di peta, bersama dengan kode yang akan menangani pergerakan mereka. Untungnya, menghapus ikatan ke negara global hanya membutuhkan beberapa hari, dan memindahkan kode ke kode lokal bahkan menyederhanakan aplikasi. Dan tentu saja, ini adalah pengalaman yang baik :)
Koneksi Layanan
Ternyata banyak layanan berbayar menyediakan layanan mereka secara gratis untuk proyek sumber terbuka. Saya akan mendaftar hanya orang-orang yang saya terhubung ke saya sendiri.
-
Penjaga . Saya pikir layanan ini untuk menangkap kesalahan sudah umum bagi semua orang. Ketika saya baru saja menyebarkan proyek, logging terdiri dari mengirim jejak stack ke surat. Ini hanya berfungsi untuk backend, tetapi saya juga ingin melacak bug di frontend. Dan tidak sia-sia - Saya telah kehabisan batas pesan gratis hanya dalam 2 minggu. Sebagian besar kesalahan ada di perut perpustakaan peta Google, yang sekilas sangat aneh. Selama penyelidikan, ternyata itu semua salah saya. Koreksi berlangsung lebih dari sebulan, tapi itu adalah praktik penanganan kesalahan javascript yang sangat berguna.
-
crowdin.com - pelokalan. Saya berencana untuk membuat proyek ini dapat diakses oleh semua orang. Termasuk infobox yang ditampilkan dalam bahasa aslinya. Mengisi mereka dari Wikipedia bukan masalah, tetapi untuk konsistensi saya juga ingin memiliki antarmuka dalam bahasa yang sama, dan sejauh ini telah diterjemahkan hanya ke dalam bahasa Rusia dan Inggris.

-
CircleCI . Tidak ada proyek modern yang dapat dilakukan tanpa CI / CD, tes dan penyebaran otomatis. Saya memilih CircleCI semata-mata karena saya sudah bekerja dengan TravisCI ketika saya menulis
perpustakaan untuk bekerja dengan Yandex.Disk . Saya mendapat kesan bahwa itu lebih cocok untuk menguji perpustakaan, sebagai mudah untuk mengatur matriks lingkungan di mana kode harus diuji. Tetapi dengan tes itu sendiri saya punya masalah - jumlahnya tidak sebanyak yang kita inginkan, meskipun infrastrukturnya sudah siap.

-
Baju . Layanan visualisasi cakupan kode. Mampu juga memberikan label untuk dimasukkan ke dalam proyek README.md.
-
SonarQube . Pemanen untuk kontrol kualitas kode. Ini memeriksa kode sesuai dengan berbagai aturan, mempertimbangkan kompleksitas cyclomatic, memantau cakupan dengan tes dan bahkan mengenali duplikasi kode! Layanan yang sangat menarik, yang belum sempat saya pahami sepenuhnya.

- Bot Github. Sejauh ini, hanya
Dependabot yang terhubung, yang memperbarui dependensi.

Saya menyarankan di komentar untuk membagikan daftar layanan dan bot pada proyek mereka.
Bug
Analisis bug dan masalah layak mendapatkan artikel terpisah. Ada yang lucu, rumit, dan sulit diperbaiki (oleh karena itu, Chukotka selalu berdiri di tempatnya). Saat ini, ada satu yang benar-benar mengganggu pengguna. Setelah menerima jawaban, poligon dihapus dan diciptakan kembali (di perpustakaan react-google-maps), dan jika pada saat itu pengguna menyeretnya, peta google terus mengasumsikan bahwa prosesnya belum selesai. Sepertinya dalam proses drag'n'drop poligon menghilang, dan Anda tidak bisa lagi mengambil yang lain. Anda dapat, tentu saja, meletakkan kunci pada pemrosesan respons dalam proses drag'n'drop, tetapi ini dijamin akan mematikan game multi-pemain, implementasi yang saat ini saya kerjakan. Saya mencoba menemukan cara untuk menghentikan drag and drop secara terprogram, tetapi pada akhirnya saya
mengajukan pertanyaan tentang StackOverflow dan
bug di Google Maps dengan harapan mereka akan memperhatikannya. Sampai saat itu, ia menambahkan tombol βgame is broken!β, Yang menginisialisasi ulang seluruh peta, tetapi tidak mereset hasilnya.
Apa selanjutnya
- Desain Saya akui bahwa dengan ini, semuanya benar-benar buruk. Adalah perlu untuk menyewa seorang desainer dan desainer tata letak, karena saya sendiri tidak berteman dengan tata letak dan tata letak.
- Monetisasi. Awalnya, saya tidak merencanakan apa pun. Proyek ini didedikasikan untuk pendidikan dasar, yang menurut saya harus dapat diakses oleh semua orang. Saya sangat terinspirasi oleh surat dari sekolah Denmark, tetapi hampir setahun berlalu, dan selama waktu itu hanya ada satu transfer $ 5. Ya, saya tidak percaya itu bisa membayar server. Namun, ia memulai kampanye di Patreon . Pada saat yang sama, Anda mungkin dapat berpikir tentang memperkenalkan peluang berbayar untuk guru atau organisasi. Sebagai contoh, saya memiliki pengalaman berintegrasi dengan Learning Management Systems - satu set platform yang memungkinkan Anda membuat kursus, dan sangat populer di Eropa dan Amerika Serikat. Sejauh yang saya mengerti, meskipun kode sumber juga di bawah GPL di Github, ini tidak mencegah saya, sebagai penulis, untuk mengembangkan versi komersial paralel.
- Ponsel. Saya ingin merilis aplikasi untuk iOS / Android. Dilihat oleh metrik Yandex, seperempat pengguna mencoba bermain dari ponsel atau tablet, tetapi ternyata mereka mengalami kesulitan.
- Pengembangan. Semua pekerjaan dilakukan di GitHub . Saya ingin terus mengembangkan proyek, tetapi melakukannya sendirian itu sulit. Rencana tersebut termasuk menambahkan multipemain, membuat tag, memberi peringkat, dan menyaring dalam Lokakarya, menambahkan poligon untuk peta fisik (gunung, laut, semenanjung). Masih ada banyak hal menarik, jadi salah satu tujuan artikel ini adalah untuk menemukan orang yang berpikiran sama. Pilihan lain adalah pergi ke yayasan, misalnya, Python Software Foundation dan mendapatkan hibah.
Inilah yang saat ini. Terima kasih sudah membaca sampai akhir! Anda dapat bermain di sini -
geopuzzle.org , dan lihat kode sumber di
GitHub .

Menit perawatan UFO
Bahan ini dapat menyebabkan perasaan yang saling bertentangan, jadi sebelum menulis komentar, segarkan sesuatu yang penting dalam ingatan Anda: