Carte des données du groupe de points de la préfecture de Shizuoka GitHub - shizokaPCDB
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.).
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.
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 ":".
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.
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
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.
À 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