[PYTHON] J'ai essayé d'afficher les données du groupe de points DB de la préfecture de Shizuoka avec Vue + Leaflet

Ce que j'ai fait cette fois

Carte des données du groupe de points de la préfecture de Shizuoka GitHub - shizokaPCDB スクリーンショット 2020-01-16 1.35.33.png

Mise en garde

Cet article n'est pas un article qui affiche les données LIDAR dans Leaflet. Il affiche les informations de la base de données des groupes de points (lieu d'acquisition des données, date de construction, etc.).

introduction

スクリーンショット 2020-01-16 1.49.59.png La préfecture de Rock Shizuoka dispose d'un grand nombre de données LIDAR de produits de construction sous forme de données ouvertes sur son propre site Web Shizuoka Point Cloud DB (ci-après dénommé «Shizuoka PCDB»). C'est ouvert au public. Quand j'ai regardé la source avec intérêt, j'ai réalisé qu'il était possible d'obtenir des données de l'extérieur (car JavaScript était écrit directement en html). Cependant, comme vous pouvez le voir sur ce site et dans l'image ci-dessus, (1) le nombre de marqueurs est important et les performances sont affectées, et (2) chaque fois que la zone de la carte change, les données contenues dans cette zone sont acquises à partir du serveur et les performances se détériorent davantage. Je pensais qu'il y avait deux problèmes: ce que je faisais. Je pensais qu'il y aurait place à amélioration si les données pouvaient être obtenues de l'extérieur, j'ai donc décidé de les développer.

Pour cette raison, nous l'enverrons de deux manières: accès et mise en forme de la base de données et affichage à la réception.

Technologie utilisée

Accès et mise en forme de la base de données

accès

En regardant la source de Shizuoka PCDB, l'accès au serveur et l'affichage dans Leaflet ont été implémentés avec environ 100 lignes. La partie qui récupère les données du serveur est illustrée ci-dessous.


var data = { request : "MarkerSet",
                Xmax : map.getBounds().getNorthEast().lng,
                Xmin : map.getBounds().getSouthWest().lng ,
                Ymax : map.getBounds().getNorthEast().lat,
                Ymin : map.getBounds().getSouthWest().lat };
    $.ajax("ankenmapsrc",{
        type: "GET",
        data: data,
        success: function(data, dataType){
            var myIcon = L.icon({
                iconUrl: 'http://cdn.leafletjs.com/leaflet-0.5/images/[email protected]',
                iconSize: [15,25],
                iconAnchor: [5, 5],
            });
//Le traitement suivant se poursuit

Si vous accédez à ankenmapsrc avec les données de la requête, vous pouvez obtenir les données. Ici, les données portent le nom de requête "MarkerSet" et Xmax, Xmin, Ymax, Ymin indiquant la zone à acquérir. La zone affichée par Leaflet est stockée dans les quatre variables de la zone. Ce processus est appelé chaque fois que la zone d'affichage de la brochure est mise à jour. En d'autres termes, les données sont acquises à chaque fois auprès du serveur.

Regardons maintenant la valeur de retour de cette requête.

30XXX01010001:Activité de mesure de four Reflex Nagiyama 2018:138.96214537214:35.03962001009?
28XXX00030007:Projet d'entretien n ° 7 de la zone du pont Shiraito no Taki Takimi:138.58870495572:35.312506370532?
28XXX00030008:Projet d'entretien n ° 8 de la zone du pont Shiraito no Taki Takimi:138.58881502806:35.312596432406?
28XXX00030009:Projet d'entretien n ° 9 de la zone du pont Shiraito no Taki Takimi:138.58892510063:35.312686494178?
29C2001011361:2017 [29-C2001-No. 01] Enquête externalisée sur les publicités extérieures sur la péninsule d'Izu (Kannan Town Road)_1-Ligne 2):138.93794860595:35.083520492945
...

À l'origine, il n'y a pas de saut de ligne, mais il est ajouté pour explication. En regardant ces données, vous pouvez voir que le délimiteur pour chaque construction est "?" Et le délimiteur pour chaque élément de données est ":".

Façonner

Accédez à Shizuoka PCDB avec Flask et créez un serveur API qui répond aux données formatées.

import urllib.request, urllib.parse
import json
@app.route('/markers')
def getMarkers():
    #Définissez la latitude et la longitude, y compris toute la préfecture de Shizuoka, sous forme de valeur entière pour acquérir tous les cas.
    xMax = 140
    xMin = 137
    yMax = 36
    yMin = 33

    params = {
        'request':'MarkerSet',
        'Xmax':xMax,
        'Xmin':xMin,
        'Ymax':yMax,
        'Ymin':yMin
    }
    p = urllib.parse.urlencode(params)
    url = "https://pointcloud.pref.shizuoka.jp/lasmap/ankenmapsrc?" + p

    #Demander à SIZUOKA POINT CLOUD DB avec le paramètre URL généré ci-dessus et obtenir la chaîne de caractères de la liste des sujets
    allAnkenStr = ""
    with urllib.request.urlopen(url) as res:
        allAnkenStr = res.read().decode()

    #Créer json pour retourner
    ankensObj = {
        "ankenList":[]
    }

    ankenList = allAnkenStr.split('?')
    for anken in ankenList:
        ankenInfo = anken.split(':')
        #S'il y a des données inappropriées, ignorez-les
        if len(ankenInfo) != 4:
            continue

        #Convertir le calendrier japonais en calendrier occidental
        yy = int(ankenInfo[0][:2])
        #Reiwa
        if yy < 24:
            yyyy = 2018 + yy
        else:
            yyyy = 1988 + yy

        ankenObj = {
            "no":ankenInfo[0],
            "name":ankenInfo[1],
            "lon":ankenInfo[2],
            "lat":ankenInfo[3],
            "year":yyyy
        }
        ankensObj['ankenList'].append(ankenObj)
    return jsonify(ankensObj)

Problèmes expliqués au début (2) Chaque fois que la zone de la carte change, les données contenues dans cette zone sont acquises à partir du serveur et les performances sont encore réduites. Il a été résolu par. C'est parce que le nombre total de cas était d'environ 1 400, et qu'il n'était pas trop tard pour les obtenir tous, alors nous avons conclu que nous devrions tous les traiter en premier.

Nous avons décidé d'analyser les données anken acquises et de renvoyer le numéro de construction, le nom de la construction, la longitude / latitude et l'année de construction sous la forme json.

Affichage à l'avant

Problèmes restants (1) Le nombre de marqueurs est important et les performances sont affectées, mais je pensais que cela serait résolu s'il était affiché avec Mapbox GL JS, qui fonctionne rapidement. Cependant, lorsque je l'ai implémenté, l'affichage des marqueurs est devenu plus lent que celui de Leaflet. J'ai donc résolu ce problème en adoptant le cluster de marqueurs de Leaflet.

Concernant la construction de l'environnement de Leaflet et Vue, Try # 027 - J'ai essayé de construire l'environnement de développement de Leaflet et Mapbox GL JS avec Vue.js Je vais l'omettre car il est détaillé. De plus, installez vue2-leaflet-markercluster.

npm install vue2-leaflet-markercluster

Communication asynchrone avec le serveur API avec Vue

Utilisez l'API Fetch. Obtenez les données avec App.vue et transmettez-les à MapPane.vue.

App.vue


<MapPane :ankens="ankens"/>

App.vue


  data() {
    return {
      ankens:[],
    }
  },
  created() {
    let vm = this
    fetch("/markers")
    .then(response => {
        return response.json()
    })
    .then(data => {
        //Après le tri, je passe des données
        vm.ankens = data.ankenList.sort(function (a, b) {
            if (a.no < b.no) {
                return 1
            }
            if (a.no > b.no) {
                return -1
            }
            return 0 
        }).sort(function (a, b) {
            if (a.year < b.year) {
                return 1
            }
            if (a.year > b.year) {
                return -1
            }
            return 0 
        })
    })
    .catch(error => {
        console.log(error)
        alert("Une erreur est survenue.")
    });
  }

MapPane.vue


<template>
    <div class="mapPane">
        <l-map
            :zoom="zoom"
            :center="center"
            :preferCanvas="true"
        >
            <l-control-scale
                position="bottomleft"
                :imperial="false"
                :metric="true"
            ></l-control-scale>

            <l-tile-layer
                :name="tileProvider.name"
                :visible="tileProvider.visible"
                :url="tileProvider.url"
                :attribution="tileProvider.attribution"
            ></l-tile-layer>

            <Vue2LeafletMarkerCluster :options="clusterOptions" >
                <LMarker v-for="anken in ankens" :key="anken.no" :lat-lng="makeLatLng(anken)" @click="onMarkerClick(anken.no)">
                    <LPopup :content="makeMarkerContent(anken)" ></LPopup>
                </LMarker>
            </Vue2LeafletMarkerCluster>
        </l-map>
    </div>
</template>

MapPane.vue



props: {
    ankens:Array
},

MapPane.vue


<style scoped>
    @import "~leaflet.markercluster/dist/MarkerCluster.css";
    @import "~leaflet.markercluster/dist/MarkerCluster.Default.css";

</style>

Enveloppez LMarker dans Vue2LeafletMarkerCluster et cela fonctionnera. En conséquence, les marqueurs de fermeture forment un cluster (bundle) et sont affichés ensemble comme une seule entité jusqu'à ce qu'elle se développe. En conséquence, le problème (1) a également été résolu.

en conclusion

À l'avenir, j'aimerais pouvoir trier et rechercher l'affichage de la liste de données et afficher l'animation en cours de chargement. Lorsque je recherchais les données LIDAR, je suis arrivé à Shizuoka PCDB, mais c'était un grand déraillement inattendu. M. Shizuoka, qui utilise une telle quantité de données précieuses comme données ouvertes, est vraiment Rock, et récemment la préfecture de Hyogo semble avoir rejoint les rangs de Rocker. Je pense que ce projet est un peu différent du courant d'utilisation des données ouvertes, mais au moins je pense qu'il est devenu une auto-amélioration. Je souhaite continuer à installer une antenne dans la zone de données ouvertes.

Recommended Posts

J'ai essayé d'afficher les données du groupe de points DB de la préfecture de Shizuoka avec Vue + Leaflet
J'ai essayé de sauvegarder les données avec discorde
J'ai essayé de visualiser les données de course du jeu de course (Assetto Corsa) avec Plotly
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé de trouver la moyenne de plusieurs colonnes avec TensorFlow
J'ai essayé d'analyser les données du tournoi de football de la Coupe du monde de football en Russie avec l'action de football
J'ai essayé d'automatiser l'arrosage du pot avec Raspberry Pi
J'ai essayé d'agrandir la taille du volume logique avec LVM
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
J'ai essayé d'obtenir le code d'authentification de l'API Qiita avec Python.
J'ai essayé d'extraire automatiquement les mouvements des joueurs Wiire avec un logiciel
J'ai essayé d'analyser la négativité de Nono Morikubo. [Comparer avec Posipa]
J'ai essayé de rationaliser le rôle standard des nouveaux employés avec Python
J'ai essayé de visualiser le texte du roman "Weather Child" avec Word Cloud
J'ai essayé d'obtenir les informations sur le film de l'API TMDb avec Python
J'ai essayé d'afficher la valeur d'altitude du DTM dans un graphique
J'ai essayé de prédire le comportement du nouveau virus corona avec le modèle SEIR.
J'ai essayé d'obtenir et d'analyser les données statistiques de la nouvelle Corona avec Python: données de l'Université John's Hopkins
Comme c'est le 20e anniversaire de la formation, j'ai essayé de visualiser les paroles de Parfum avec Word Cloud
J'ai essayé d'obtenir des données CloudWatch avec Python
J'ai essayé de corriger la forme trapézoïdale de l'image
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
J'ai essayé de visualiser facilement les tweets de JAWS DAYS 2017 avec Python + ELK
[IBM Cloud] J'ai essayé d'accéder à la table Db2 on Cloud à partir de Cloud Funtions (python)
J'ai essayé de récupérer les données de l'ordinateur portable en le démarrant sur Ubuntu
[Vérification] Essayez d'aligner le groupe de points avec la fonction d'optimisation de pytorch Partie 1
L'histoire de la fabrication de soracom_exporter (j'ai essayé de surveiller SORACOM Air avec Prometheus)
J'ai essayé d'afficher le degré d'infection par le virus corona sur la carte thermique Seaborn
J'ai essayé de créer un modèle avec l'exemple d'Amazon SageMaker Autopilot
J'ai essayé d'envoyer automatiquement la littérature du nouveau virus corona à LINE avec Python
J'ai essayé d'entraîner la fonction péché avec chainer
J'ai essayé d'extraire des fonctionnalités avec SIFT d'OpenCV
J'ai essayé de résumer la forme de base de GPLVM
J'ai essayé de toucher un fichier CSV avec Python
J'ai essayé de prédire le match de la J League (analyse des données)
J'ai essayé de résoudre Soma Cube avec python
J'ai essayé de créer un pipeline ML avec Cloud Composer
J'ai essayé d'utiliser l'API de Sakenowa Data Project
J'ai essayé de visualiser les informations spacha de VTuber
J'ai essayé d'effacer la partie négative de Meros
J'ai essayé de résoudre le problème avec Python Vol.1
J'ai essayé de classer les voix des acteurs de la voix
J'ai essayé de résumer les opérations de chaîne de Python
J'ai essayé de faire quelque chose comme un chatbot avec le modèle Seq2Seq de TensorFlow
J'ai essayé d'automatiser la mise à jour de l'article du blog Livedoor avec Python et sélénium.
J'ai essayé de visualiser les caractéristiques des nouvelles informations sur les personnes infectées par le virus corona avec wordcloud
[First data science ⑥] J'ai essayé de visualiser le prix du marché des restaurants à Tokyo
Je voulais juste extraire les données de la date et de l'heure souhaitées avec Django
J'ai essayé de comparer la vitesse de traitement avec dplyr de R et pandas de Python
Le 15e temps réel hors ligne, j'ai essayé de résoudre le problème de l'écriture avec python
J'en ai marre de Python, alors j'ai essayé d'analyser les données avec nehan (je veux aller vivre même avec Corona) -Partie 2)
J'en ai marre de Python, alors j'ai essayé d'analyser les données avec nehan (je veux aller vivre même avec Corona) -Partie 1)
[Courses de chevaux] J'ai essayé de quantifier la force du cheval de course
J'ai essayé de simuler la propagation de l'infection avec Python
J'ai essayé d'analyser les émotions de tout le roman "Weather Child" ☔️
J'ai essayé d'obtenir les informations de localisation du bus Odakyu