Suite

Inclinaison d'OpenStreetMap avec LeafletJs

Inclinaison d'OpenStreetMap avec LeafletJs


J'utilise LeafletJs comme bibliothèque de cartographie pour OpenStreetMaps. Existe-t-il une méthode map.Tilt () dans Leaflet api comme Google le fournit

map = new google.maps.Map(document.getElementById('map-canvas'), { zoom: 18, center: new google.maps.LatLng(35.8313284, -82.7251666), mapTypeId: google.maps.MapTypeId.SATELLITE, cap : 90, inclinaison : 30 });

Je n'ai pas besoin de vue SATELLITE. Récemment, je regarde des marqueurs comme celui-ci. Je dois montrer la carte à un angle de 20/30 degrés.


Il n'y a pas de fonctionnalité intégrée pour cela dans Leaflet, et aucun plugin pour le faire à ma connaissance non plus.

Vous pourriez peut-être produire quelque chose comme ça avec du CSStransformer3dhack, mais cela aurait probablement l'air assez horrible.

En général, je pense qu'OpenLayers 3 pourrait être plus adapté aux fonctionnalités pseudo-3D. Cependant, je n'ai pas utilisé OpenLayers 3 moi-même.


Cela peut être accompli en utilisant une transformation css, mais cela n'a pas l'air génial, mais cela fonctionne assez bien pour certaines choses. La capture d'écran ci-dessous utilise le style :transformer : translate3d(-300px, -141px, 0px)sur le div contenant la carte.


Si votre dépliant carte fonctionne soudainement correctement après avoir redimensionné la fenêtre de votre navigateur, alors vous rencontrez le classique "Taille du conteneur de carte non valide à l'initialisation de la carte": pour fonctionner correctement, Leaflet lit la taille du conteneur de la carte lorsque vous initialisez la carte ( L.map("mapContainerId") ).

Si votre application masque ce conteneur (généralement via l'affichage CSS : aucun , ou un onglet de framework / modal / quoi que ce soit…) ou modifie plus tard ses dimensions, Leaflet ne sera pas au courant de la nouvelle taille. Par conséquent, il ne sera pas rendu correctement. En règle générale, il ne télécharge les tuiles que pour la fraction du conteneur qu'il pense être affiché. Il peut s'agir d'une seule tuile dans le coin supérieur gauche dans le cas d'un conteneur entièrement masqué au moment de l'initialisation de la carte.

Cette erreur se produit souvent lors de l'intégration du conteneur de carte dans un panneau "onglet" ou "modal", éventuellement en utilisant des frameworks populaires (Bootstrap, Angular, Ionic, etc.).

Leaflet écoute l'événement de redimensionnement de la fenêtre du navigateur et relit la taille du conteneur lorsqu'il se produit. Cela explique pourquoi la carte fonctionne soudainement sur le redimensionnement de la fenêtre.

Vous pouvez également déclencher manuellement cette mise à jour en appelant map.invalidateSize() lorsque le panneau d'onglets est affiché (par exemple, ajoutez un écouteur au clic sur le bouton d'onglet), au moins la première fois que le conteneur est rendu avec ses dimensions correctes.

En ce qui concerne la mise en œuvre de l'écouteur de clic sur le bouton d'onglet, effectuez une nouvelle recherche sur SO sur ce sujet : vous devriez avoir beaucoup de ressources disponibles à cet effet, pour la plupart des frameworks populaires.


Quoi de neuf dans la brochure DVF

OK, OK, ça fait un moment depuis mon dernier article de blog. J'avais de grandes visions d'écrire des articles tous les mois ou tous les deux mois, mais le travail et la vie m'ont rattrapé. Cela fait environ un an que le Leaflet DVF est officiellement sorti sur GitHub, je voulais donc partager quelques mises à jour sur l'état du framework. De plus, cet article est une sorte de fourre-tout pour des choses sur lesquelles je n'ai pas écrit au cours de l'année dernière, ce qui était tout nouveau dans le DVF, alors attendez-vous à voir beaucoup de captures d'écran, de brefs résumés et des exemples qui auraient probablement pu justifier leur mes propres articles de blog si j'avais mieux réussi à les écrire.

Si vous n'avez pas lu mes articles précédents présentant le DVF et certaines de ses fonctionnalités de base, le DVF a commencé comme mon projet parallèle chez HumanGeo. J'ai réalisé que je dupliquais du code de visualisation géospatiale et je voulais expérimenter la création d'un ensemble générique d'outils qui facilitent autant que possible la visualisation des données géospatiales à l'aide de Leaflet, même lorsque GeoJSON bien formaté n'est pas disponible. Ce cadre m'a donné l'opportunité de faire exactement cela. Je suis heureux d'annoncer que le DVF se porte bien avec un soutien, une adoption et une participation accrus de la communauté, ainsi qu'une multitude de nouvelles fonctionnalités.

En passant, et avant de me plonger dans certaines des nouvelles fonctionnalités du DVF, nous avons récemment mis à jour notre site Web. Depuis que j'ai aidé à concevoir et à construire le site, sans surprise, le DVF est mis en évidence - utilisé dans la visite de la carte principale en haut de la page d'accueil, combiné à une superbe carte d'arrière-plan aquarelle Stamen et à quelques effets de parallaxe sympas utilisant parallax.js . Vérifiez-le dans un navigateur moderne. Cliquez simplement sur le logo HumanGeo pour commencer la visite et attendez-vous à un article de blog sur la création de cette carte dans un avenir proche (par « avenir proche » je veux dire quelques semaines, pas un an).


Construire la carte du site Web HumanGeo

HumanGeo est une entreprise relativement nouvelle – la date de fondation est un peu floue, mais 4 ans semble être la notion dominante. Notre site Web n'avait pas beaucoup changé depuis plus de trois ans, et il avait l'air un peu daté, même selon les normes des sites Web vieux de trois ans, alors l'année dernière, nous avons décidé de franchir le pas et de le mettre à jour.

Voici un instantané d'Internet Archive de l'ancien site, avec le type sombre de HumanGeo (l'accent est mis sur le "Human" dans HumanGeo, peut-être ?)

Ce n'est pas que l'ancien site était mauvais, il n'était juste pas excitant, et il ne semblait pas capturer tout ce qui rend HumanGeo unique - il s'est en quelque sorte mélangé avec tous les autres sites Web d'entreprise. En construisant le nouveau site Web, nous avons entrepris de créer une expérience un peu moins corporative et un peu plus créative, avec un accent renouvelé sur la transmission concise de ce que nous faisons réellement ici. Distiller toutes les choses que nous faisons à travers les projets dans un message cohérent et clair était un défi comparable à la création du site Web lui-même, mais je garderai cette discussion pour une autre fois. Étant donné que HumanGeo est une jeune entreprise qui opère principalement dans l'espace des services, notre identité d'entreprise, bien que centrée sur quelques thèmes centraux, est en constante évolution, fortement motivée par les besoins de nos partenaires et les solutions que nous construisons collectivement. L'un des thèmes centraux qui est resté malgré les changements subtils de notre identité au fil du temps est notre concentration sur la création de solutions géospatiales. C'est le “Geo” dans HumanGeo, c'est précisément pourquoi nous avons choisi d'afficher une carte comme image de héros sur notre page principale (désolé HumanGeo guy). Cet article porte sur la construction de cette carte, qui est moins une image statique qu'une introduction dynamique dans le monde de HumanGeo. Mon objectif avec cet article est de mettre en évidence la complexité de la construction de la carte et certaines des façons dont Leaflet DVF et quelques autres bibliothèques (Stamen, TopoJSON, Parallax JS) ont simplifié le développement ou ajouté quelque chose de spécial.

Lorsque vous arrivez sur notre site, vous êtes accueilli avec une grande carte basée sur Leaflet JS avec un fond d'aquarelle Stamen et quelques effets de parallaxe sympas (du moins, je pense que c'est cool). C'est plus artistique que réaliste (l'utilisation des tuiles de carte aquarelle Stamen nous a presque forcé la main stylistiquement), une tentative de souligner notre côté créatif et imaginatif tout en soulignant le fait que la géospatiale est une grande partie de la plupart des solutions que nous construisons . La carte est centrée sur DC avec le bureau de HumanGeo à Arlington en bas à gauche et quelques camemberts et marqueurs de couleur dans la région de DC. L'idée ici est que vous regardez notre monde d'en haut, et c'est en quelque sorte un instantané dans le temps. À tout moment, de nombreux points de données sont générés à partir de diverses sources (par exemple, des personnes utilisant les médias sociaux, des capteurs, etc.), et HumanGeo s'efforce d'aider nos partenaires à capturer, analyser et donner un sens à ces points de données. . Lorsque vous déplacez votre souris sur la carte ou inclinez votre appareil, les nuages, le satellite, l'avion et la carte se déplacent tous, simulant l'effet du changement de perspective que vous pourriez voir si vous teniez le monde entre vos mains. En général, je voulais que cette zone (l'image/zone de héros typique) soit plus qu'une simple grande image statique que vous pourriez voir sur de nombreux sites sur le Web - je voulais qu'elle soit dynamique. Si vous passez du temps à parcourir notre site, vous verrez que cette zone de héros dynamique est un élément commun à toutes les pages de notre site.

Parallaxe

Le défilement de parallaxe est populaire de nos jours, se frayant un chemin dans presque tous les modèles de sites Web prêts à l'emploi. Habituellement, vous le voyez sous la forme d'une image d'arrière-plan qui défile à une vitesse différente de celle du texte principal d'une page. Il donne la dimension de la page, comme si la page était composée de différentes couches dans un espace tridimensionnel. En général, je suis fan de cet effet. Cependant, j'ai décidé d'opter pour une approche différente pour cette refonte, principalement parce que j'ai vu une bibliothèque intéressante qui appliquait des effets de parallaxe basés sur le mouvement de la souris ou de l'appareil plutôt que sur le défilement, et l'idée de la combiner avec une carte m'intriguait. La bibliothèque à laquelle je fais référence est Parallax JS, une excellente bibliothèque qui facilite ce type d'effets. Pour créer une scène de parallaxe, vous ajoutez simplement une liste non ordonnée (ul) élément – représentant une scène – dans le corps de votre page avec un ensemble d'éléments de liste enfants (je suis) éléments qui représentent les différentes couches de la scène. Chaque je suis élément comprend un profondeur des données attribut qui va de 0,0 à 1,0 et spécifie à quelle distance ou à quelle distance du spectateur cette couche apparaîtra (la proximité implique que le mouvement sera plus exagéré). Une valeur de 0,0 indique que le calque sera le plus bas de la liste et ne bougera pas, tandis qu'une valeur de 1,0 signifie que le calque se déplacera le plus. Dans ce cas, ma scène est composée de la carte comme première je suis élément avec diverses couches empilées dessus, y compris les boîtiers d'imagerie satellite, le satellite, les nuages ​​et l'avion. La carte a un profondeur des données valeur de 0,05, ce qui signifie qu'il se déplacera un peu, et chaque couche au-dessus de la carte a une valeur croissante profondeur des données valeur. Voici à quoi ressemble le balisage :

Un avion en mouvement

Sur les navigateurs modernes, l'avion se déplace via des animations CSS 3, définies à l'aide d'images clés. Les images clés établissent des propriétés qui seront appliquées à l'élément HTML animé à différents points de l'animation. Dans ce cas, l'avion se déplacera selon une trajectoire linéaire de 0,800 à 250, -350 pendant toute la durée de l'animation.

Sur la carte

Les visualisations cartographiques utilisent un mélange de données réelles et simulées. Étant donné que nous sommes situés dans la région de DC, je voulais illustrer l'affichage de statistiques géographiques dans DC, mais d'abord, j'avais besoin de trouver des statistiques liées à DC. Je suis tombé sur le site du catalogue de données du bureau de l'administrateur de la ville de DC qui répertorie un certain nombre de ressources de données statistiques liées à DC. Parmi ces ressources figurent des fichiers à valeurs séparées par des virgules (CSV) de tous les lieux d'incidents criminels pour une année donnée, comme ce fichier, qui répertorie les incidents criminels pour 2013. Le fichier CSV classe chaque incident selon un certain nombre d'attributs et de catégories de limites administratives, y compris Cité de vote DC. J'ai décidé d'utiliser les bureaux de vote DC comme base pour afficher les statistiques géographiques, car cela illustrerait bien l'utilisation de limites administratives de niveau inférieur, et il y a suffisamment de bureaux de vote DC pour rendre la carte intéressante par rapport à l'utilisation d'un autre niveau de limite administrative comme les huit quartiers à DC. J'ai téléchargé le fichier de formes des enceintes DC sur le site Web de DC Atlas, puis j'ai utilisé QGIS pour le convertir en GeoJSON afin de le rendre facilement analysable en JavaScript. À ce stade, je suis tombé sur le premier défi. Le fichier GeoJSON résultant de l'enceinte DC est de 2,5 Mo, ce qui est évidemment assez volumineux du point de vue du chargement rapide du site Web et n'est pas une expérience frustrante pour les utilisateurs finaux.

Pour rendre ce fichier utilisable, j'ai décidé de le compresser à l'aide de la bibliothèque TopoJSON. TopoJSON est un moyen intelligent de compresser GeoJSON, inventé par Mike Bostock de D3 et New York Times renommée de visualisation. TopoJSON compresse GeoJSON en éliminant les segments de ligne redondants partagés entre les polygones (par exemple, les frontières partagées des limites des circonscriptions électorales). Au lieu que chaque polygone d'un fichier GeoJSON partage des segments de ligne redondants, TopoJSON stocke la représentation de ces segments de ligne partagés, puis chaque polygone qui contient ces segments fait référence aux segments partagés. Cela fait des choses étonnantes lorsque vous avez GeoJSON de limites administratives où ces limites incluent souvent des frontières partagées. Après avoir téléchargé TopoJSON, j'ai exécuté le script sur le fichier GeoJSON de mon quartier DC :

Notez que le -p Le paramètre est important, car il indique au script TopoJSON d'inclure les propriétés de l'entité GeoJSON dans la sortie. Si vous laissez ce paramètre désactivé, les fonctionnalités TopoJSON résultantes n'incluront pas les propriétés qui existaient dans le GeoJSON d'entrée. Dans mon cas, j'avais besoin de vote_enceinte propriété d'exister, puisque les visualisations que je construisais reposaient sur l'attachement de statistiques aux polygones de circonscription électorale, et ces polygones sont récupérés via le vote_enceinte biens. L'exécution du script TopoJSON a généré un fichier de 256 Ko, réduisant la taille du fichier d'entrée de 90 % !

Il est important de noter que dans peu fréquent les cas utilisant TopoJSON n'ont pas de sens. Vous devrez peser la taille de votre GeoJSON par rapport à l'inclusion de la bibliothèque TopoJSON (un léger 8 Ko minifié) et du traitement supplémentaire requis par le navigateur pour lire GeoJSON à partir de l'entrée TopoJSON. Ainsi, si vous avez un petit fichier GeoJSON avec un nombre relativement faible de polygones, ou si les entités surfaciques de ce fichier GeoJSON ne partagent pas de bordures, il peut ne pas être judicieux de le compresser à l'aide de TopoJSON. Si vous construisez des cartes choroplèthes en utilisant plus que quelques limites administratives, cela a presque toujours du sens.

Une fois que vous avez TopoJSON, vous devrez le décoder en GeoJSON pour le rendre utilisable. Dans ce cas:

enceinteTopo est la variable JavaScript qui fait référence à la version TopoJSON des polygones d'enceinte. enceinteTopo.objects.dcprecincts est un GeoJSON GeometryCollection qui contient chaque polygone d'enceinte. Appeler le topojson.fonctionnalité La méthode transformera cette entrée TopoJSON en GeoJSON.

Maintenant que j'avais des données et des polygones associés, j'ai décidé de créer quelques visualisations. La première visualisation illustre les crimes à Washington par circonscription électorale à l'aide d'un seul L.DataLayer instance, mais fournit des visuels différents en fonction de la zone d'entrée. Pour certaines circonscriptions, j'ai décidé d'afficher des camemberts classés par criminalité totale, et pour d'autres, j'ai décidé de dessiner un GroupeMarqueur d'empilés Marqueur de cercle instances dimensionnées et colorées par le crime.

La raison de cela est que je voulais illustrer deux capacités différentes que nous fournissons à nos partenaires, la détection d'événements à partir des médias sociaux et les statistiques géographiques. Y compris ceux-ci dans le même Couche de données instance garantit que les données statistiques ne sont analysées qu'une seule fois. Pour la couche de détection d'événements, j'ai aussi voulu pimenter un peu en ajoutant un L.Graph exemple qui illustre la propagation d'un événement dans les médias sociaux depuis son point de départ jusqu'aux zones environnantes. Dans ce cas, j'ai généré de fausses données qui représentent le mouvement d'informations entre deux circonscriptions, où chaque enregistrement est un bord. Voici à quoi ressemblent les fausses données :

Voici le code pour instancier un L.Graph instance et l'ajouter à la carte.

Les emplacements des nœuds dans le graphe sont spécifiés via le enceinte GeoJSON récupéré à partir du fichier TopoJSON dont j'ai parlé plus tôt. duChamp et versChamp dis le L.Graph exemple comment tracer des lignes entre les nœuds.

Les camemberts incluent des valeurs de tranche aléatoires. J'aurais pu utiliser les données réelles et ventiler le crime à Washington par type, mais je voulais garder les camemberts simples, et trois tranches semblaient être un bon nombre. Il y a plus de trois types de crimes qui ont été commis à DC en 2013. En passant, voici une représentation des crimes à DC codée par couleur par type en utilisant L.StackedRegularPolygonMarker instances.

Le code de cette visualisation se trouve dans les exemples DVF ici. C'est plus artistique que pratique. L'une des fonctionnalités intéressantes de Leaflet DVF est la possibilité d'échanger facilement des visualisations en modifiant quelques paramètres. 8217s utilisé (par exemple L.PieChartDataLayer, L.BarChartDataLayer, etc.) et en modifiant certaines options.

Après avoir décidé quelles informations je voulais afficher à l'aide de camemberts, je me suis aventuré sur le site Web de Color Brewer et j'ai opté pour certaines couleurs. 3 classe Accent schéma de couleurs dans le qualitatif section ici – qui fonctionnent bien ensemble tout en s'adaptant au schéma de couleurs pastel qui prévaut dans les carreaux de fond aquarelle Stamen. Le Leaflet DVF prend en charge les schémas de couleurs Color Brewer (en utilisant le L.ColorBrewer objet), donc si vous voyez un schéma de couleurs que vous aimez sur le site Web de Color Brewer, il est facile de l'appliquer à la visualisation de carte que vous créez à l'aide de l'outil L.CustomColorFunction classe, comme ceci :

Je voulais également mettre en évidence une partie du travail que nous avons effectué en ce qui concerne l'analyse de la mobilité, j'ai donc réutilisé les données de course de l'exemple Leaflet DVF Run Map et stylisé le Polyligne pondérée afin qu'elle s'intègre mieux à notre carte aquarelle Stamen, en utilisant un jeu de couleurs blanc à violet. Les données d'exécution ressemblent à ceci :

Consultez l'exemple Run Map pour voir comment ces données peuvent être transformées en une ligne pondérée variable ou l'exemple GPX Analyzer qui vous permet de faire glisser et de déposer des fichiers GPS Exchange Format (GPX) (un format commun pour capturer des données de waypoint/voyage GPS) sur la carte pour voir les variations de la vitesse de votre course/vélo/ou autre voyage dans l'espace et le temps.

Pour rendre la carte un peu plus intéressante, j'ai ajouté des couches supplémentaires pour notre bureau, nos employés et certains bateaux dans l'eau (les emplacements des employés et des bateaux sont constitués). Maintenant que j'avais les couches de carte que je voulais utiliser, je les ai intégrées dans une visite qui permet à un utilisateur de naviguer sur la carte comme une présentation PowerPoint. J'ai construit une classe de visite simple qui a des méthodes pour naviguer en avant et en arrière. Chaque action de visite se compose d'un élément HTML avec un texte explicatif et une fonction associée à exécuter lorsque cette action se produit. Dans ce cas, la fonction à exécuter implique généralement un panoramique/un zoom sur une autre couche de la carte ou l'affichage/le masquage des couches de la carte. Les détails de l'interaction de la visite vont au-delà de la collecte, de la transformation et de la visualisation de données géospatiales, alors n'hésitez pas à explorer le code ici et à découvrir la visite par vous-même en visitant notre site et en cliquant sur le logo HumanGeo.


Tilt d'OpenStreetMap avec LeafletJs - Systèmes d'Information Géographique

7 contributeurs

Utilisateurs ayant contribué à ce fichier

# (PARTIE) Extensions
# Faire des cartes avec R
## Conditions préalables
- Ce chapitre nécessite les packages suivants que nous avons déjà utilisés :
```
bibliothèque ( sf )
bibliothèque( raster )
bibliothèque ( dplyr )
bibliothèque( spData )
bibliothèque( spDataLarge )
```
- De plus, il utilise les packages de visualisation suivants (installez également shiny si vous souhaitez développer des applications cartographiques interactives) :
```
library( tmap ) # pour les cartes statiques et interactives
bibliothèque (dépliant) # pour les cartes interactives
bibliothèque ( ggplot2 ) # package de visualisation de données tidyverse
```
## Introduction
Un aspect satisfaisant et important de la recherche géographique est la communication des résultats.
La fabrication de cartes --- l'art de la cartographie --- est une compétence ancienne qui implique la communication, l'intuition et un élément de créativité.
Le mappage statique est simple avec `plot()` , comme nous l'avons vu dans la section @ ref(basic-map).
Il est possible de créer des cartes avancées en utilisant les méthodes de base R [ @ murrell_r_2016 ], mais ce chapitre se concentre sur les packages de création de cartes dédiés.
Lors de l'apprentissage d'une nouvelle compétence, il est logique d'acquérir des connaissances approfondies dans un domaine avant de se diversifier.
La création de cartes ne fait pas exception, d'où la couverture de ce chapitre d'un paquet ( ** tmap ** ) en profondeur plutôt que de nombreux superficiellement.
En plus d'être amusante et créative, la cartographie a également d'importantes applications pratiques.
Une carte soigneusement élaborée est vitale pour communiquer efficacement les résultats de votre travail [ @ brewer_designing_2015 ] :
> Les cartes d'aspect amateur peuvent nuire à la capacité de votre public à comprendre des informations importantes et affaiblir la présentation d'une enquête de données professionnelle.
Les cartes sont utilisées depuis plusieurs milliers d'années à des fins très diverses.
Les exemples historiques incluent des cartes des bâtiments et de la propriété foncière dans l'ancienne dynastie babylonienne il y a plus de 3000 ans et la carte du monde de Ptolémée dans son chef-d'œuvre *Géographie* il y a près de 2000 ans [ @ talbert_ancient_2014 ].
La cartographie a toujours été une activité entreprise uniquement par ou au nom de l'élite.
Cela a changé avec l'émergence de logiciels de cartographie open source tels que le package R **tmap** et le 'print composer' dans QGIS i ndex qui permettent à n'importe qui de créer des cartes de haute qualité, permettant ainsi à la « science citoyenne ».
Les cartes sont aussi souvent le meilleur moyen de présenter les résultats de la recherche géoinformatique d'une manière accessible.
La création de cartes est donc une partie essentielle du géocalcul i ndex et son insistance non seulement sur la description, mais aussi sur le *changement* du monde.
Ce chapitre montre comment créer un large éventail de cartes.
La section suivante couvre une gamme de cartes statiques, y compris des considérations esthétiques, des facettes et des cartes en médaillon.
Les sections @ ref(animated-maps) à @ ref(mapping-applications) couvrent les cartes animées et interactives (y compris les cartes Web et les applications cartographiques).
Enfin, la section @ ref(other-mapping-packages) couvre une gamme de packages de création de cartes alternatifs, notamment **ggplot2** et **cartogram** .
## Cartes statiques
i nindex
Les cartes statiques sont le type de sortie visuelle le plus courant du géocalcul.
Les formats standard incluent `.png` et `.pdf` pour les sorties raster et vectorielles respectivement.
Initialement, les cartes statiques étaient le seul type de cartes que R pouvait produire.
Les choses ont avancé avec la sortie de **sp** [voir @pebesma_classes_2005 ] et de nombreuses techniques de création de cartes ont été développées depuis lors.
Cependant, malgré l'innovation de la cartographie interactive, le traçage statique était toujours l'accent de la visualisation des données géographiques dans R une décennie plus tard [ @ cheshire_spatial_2015 ].
La fonction générique `plot()` est souvent le moyen le plus rapide de créer des cartes statiques à partir d'objets spatiaux vectoriels et raster (voir les sections @ ref(basic-map) et @ ref(basic-map-raster)).
Parfois, la simplicité et la rapidité sont des priorités, en particulier pendant la phase de développement d'un projet, et c'est là que `plot()` excelle.
L'approche de base R est également extensible, avec `plot()` offrant des dizaines d'arguments.
Une autre approche est le package **grid** qui permet un contrôle de bas niveau des cartes statiques, comme illustré au chapitre [ 14 ](https://www.stat.auckland.ac.nz/

Vous ne pouvez pas effectuer cette action pour le moment.

Vous vous êtes connecté avec un autre onglet ou une autre fenêtre. Recharger pour rafraîchir votre session. Vous vous êtes déconnecté dans un autre onglet ou une autre fenêtre. Recharger pour rafraîchir votre session.


Construire la carte du site Web HumanGeo

HumanGeo est une entreprise relativement nouvelle – la date de fondation est un peu floue, mais 4 ans semble être la notion dominante. Notre site Web n'avait pas beaucoup changé depuis plus de trois ans, et il avait l'air un peu daté, même selon les normes des sites Web vieux de trois ans, alors l'année dernière, nous avons décidé de franchir le pas et de le mettre à jour.

Voici un instantané d'Internet Archive de l'ancien site, avec le type sombre de HumanGeo (l'accent est mis sur le "Human" dans HumanGeo, peut-être ?)

Ce n'est pas que l'ancien site était mauvais, il n'était tout simplement pas excitant, et il ne semblait pas capturer tout ce qui rend HumanGeo unique - il s'est en quelque sorte mélangé avec tous les autres sites Web d'entreprise. En construisant le nouveau site Web, nous avons entrepris de créer une expérience un peu moins corporative et un peu plus créative, avec un accent renouvelé sur la transmission concise de ce que nous faisons réellement ici. Distiller toutes les choses que nous faisons à travers les projets dans un message cohérent et clair était un défi comparable à la création du site Web lui-même, mais je garderai cette discussion pour une autre fois. Étant donné que HumanGeo est une jeune entreprise qui opère principalement dans l'espace des services, notre identité d'entreprise, bien que centrée sur quelques thèmes centraux, est en constante évolution, fortement motivée par les besoins de nos partenaires et les solutions que nous construisons collectivement. L'un des thèmes centraux qui est resté malgré les changements subtils de notre identité au fil du temps est notre concentration sur la création de solutions géospatiales. C'est le “Geo” dans HumanGeo, c'est précisément pourquoi nous avons choisi d'afficher une carte comme image de héros sur notre page principale (désolé HumanGeo guy). Cet article porte sur la construction de cette carte, qui est moins une image statique qu'une introduction dynamique dans le monde de HumanGeo. Mon objectif avec cet article est de mettre en évidence la complexité de la construction de la carte et certaines des façons dont Leaflet DVF et quelques autres bibliothèques (Stamen, TopoJSON, Parallax JS) ont simplifié le développement ou ajouté quelque chose de spécial.

Lorsque vous arrivez sur notre site, vous êtes accueilli avec une grande carte basée sur Leaflet JS avec un fond d'aquarelle Stamen et quelques effets de parallaxe sympas (du moins, je pense que c'est cool). C'est plus artistique que réaliste (l'utilisation des tuiles de carte aquarelle Stamen nous a presque forcé la main stylistiquement), une tentative de souligner notre côté créatif et imaginatif tout en soulignant le fait que la géospatiale est une grande partie de la plupart des solutions que nous construisons . La carte est centrée sur DC avec le bureau de HumanGeo à Arlington en bas à gauche et quelques camemberts et marqueurs de couleur dans la région de DC. L'idée ici est que vous regardez notre monde d'en haut, et c'est en quelque sorte un instantané dans le temps. À tout moment, de nombreux points de données sont générés à partir de diverses sources (par exemple, des personnes utilisant les médias sociaux, des capteurs, etc.), et HumanGeo s'efforce d'aider nos partenaires à capturer, analyser et donner un sens à ces points de données. . Lorsque vous déplacez votre souris sur la carte ou inclinez votre appareil, les nuages, le satellite, l'avion et la carte se déplacent tous, simulant l'effet du changement de perspective que vous pourriez voir si vous teniez le monde entre vos mains. En général, je voulais que cette zone (l'image/zone de héros typique) soit plus qu'une simple grande image statique que vous pourriez voir sur de nombreux sites sur le Web - je voulais qu'elle soit dynamique. Si vous passez du temps à parcourir notre site, vous verrez que cette zone de héros dynamique est un élément commun à toutes les pages de notre site.

Parallaxe

Le défilement de parallaxe est populaire de nos jours, se frayant un chemin dans presque tous les modèles de sites Web prêts à l'emploi. Habituellement, vous le voyez sous la forme d'une image d'arrière-plan qui défile à une vitesse différente de celle du texte principal d'une page. Il donne la dimension de la page, comme si la page était composée de différentes couches dans un espace tridimensionnel. En général, je suis fan de cet effet. Cependant, j'ai décidé d'opter pour une approche différente pour cette refonte, principalement parce que j'ai vu une bibliothèque intéressante qui appliquait des effets de parallaxe basés sur le mouvement de la souris ou de l'appareil plutôt que sur le défilement, et l'idée de la combiner avec une carte m'intriguait. La bibliothèque à laquelle je fais référence est Parallax JS, une excellente bibliothèque qui facilite ce type d'effets. Pour créer une scène de parallaxe, vous ajoutez simplement une liste non ordonnée (ul) élément – représentant une scène – dans le corps de votre page avec un ensemble d'éléments de liste enfants (je suis) éléments qui représentent les différentes couches de la scène. Chaque je suis élément comprend un profondeur des données attribut qui va de 0,0 à 1,0 et spécifie à quelle distance ou à quelle distance du spectateur cette couche apparaîtra (la proximité implique que le mouvement sera plus exagéré). Une valeur de 0,0 indique que le calque sera le plus bas de la liste et ne bougera pas, tandis qu'une valeur de 1,0 signifie que le calque se déplacera le plus. Dans ce cas, ma scène est composée de la carte comme première je suis élément avec diverses couches empilées dessus, y compris les boîtiers d'imagerie satellite, le satellite, les nuages ​​et l'avion. La carte a un profondeur des données valeur de 0,05, ce qui signifie qu'il se déplacera un peu, et chaque couche au-dessus de la carte a une valeur croissante profondeur des données valeur. Voici à quoi ressemble le balisage :

Un avion en mouvement

Sur les navigateurs modernes, l'avion se déplace via des animations CSS 3, définies à l'aide d'images clés. Les images clés établissent des propriétés qui seront appliquées à l'élément HTML animé à différents points de l'animation. Dans ce cas, l'avion se déplacera selon une trajectoire linéaire de 0,800 à 250, -350 pendant toute la durée de l'animation.

Sur la carte

Les visualisations cartographiques utilisent un mélange de données réelles et simulées. Étant donné que nous sommes situés dans la région de DC, je voulais illustrer l'affichage de statistiques géographiques dans DC, mais d'abord, j'avais besoin de trouver des statistiques liées à DC. Je suis tombé sur le site du catalogue de données du bureau de l'administrateur de la ville de DC qui répertorie un certain nombre de ressources de données statistiques liées à DC. Parmi ces ressources figurent des fichiers à valeurs séparées par des virgules (CSV) de tous les lieux d'incidents criminels pour une année donnée, comme ce fichier, qui répertorie les incidents criminels pour 2013. Le fichier CSV classe chaque incident selon un certain nombre d'attributs et de catégories de limites administratives, y compris Cité de vote DC. J'ai décidé d'utiliser les bureaux de vote DC comme base pour afficher les statistiques géographiques, car cela illustrerait bien l'utilisation de limites administratives de niveau inférieur, et il y a suffisamment de bureaux de vote DC pour rendre la carte intéressante par rapport à l'utilisation d'un autre niveau de limite administrative comme les huit quartiers à DC. J'ai téléchargé le fichier de formes des enceintes DC sur le site Web de DC Atlas, puis j'ai utilisé QGIS pour le convertir en GeoJSON afin de le rendre facilement analysable en JavaScript. À ce stade, je suis tombé sur le premier défi. Le fichier GeoJSON résultant de l'enceinte DC est de 2,5 Mo, ce qui est évidemment assez volumineux du point de vue du chargement rapide du site Web et n'est pas une expérience frustrante pour les utilisateurs finaux.

Pour rendre ce fichier utilisable, j'ai décidé de le compresser à l'aide de la bibliothèque TopoJSON. TopoJSON est un moyen intelligent de compresser GeoJSON, inventé par Mike Bostock de D3 et New York Times renommée de visualisation. TopoJSON compresse GeoJSON en éliminant les segments de ligne redondants partagés entre les polygones (par exemple, les frontières partagées des limites des circonscriptions électorales). Au lieu que chaque polygone d'un fichier GeoJSON partage des segments de ligne redondants, TopoJSON stocke la représentation de ces segments de ligne partagés, puis chaque polygone qui contient ces segments fait référence aux segments partagés. Cela fait des choses étonnantes lorsque vous avez GeoJSON de limites administratives où ces limites incluent souvent des frontières partagées. Après avoir téléchargé TopoJSON, j'ai exécuté le script sur le fichier GeoJSON de mon quartier DC :

Notez que le -p est important, car il indique au script TopoJSON d'inclure les propriétés de l'entité GeoJSON dans la sortie. Si vous laissez ce paramètre désactivé, les fonctionnalités TopoJSON résultantes n'incluront pas les propriétés qui existaient dans le GeoJSON d'entrée. Dans mon cas, j'avais besoin de bureau_de_vote propriété d'exister, puisque les visualisations que je construisais reposaient sur l'attachement de statistiques aux polygones de circonscription électorale, et ces polygones sont récupérés via le bureau_de_vote biens. Running the TopoJSON script yielded a 256 KB file, reducing the size of the input file by 90%!

It’s important to note that in peu fréquent cases using TopoJSON doesn’t make sense. You’ll have to weigh the size of your GeoJSON versus including the TopoJSON library (a light 8 KB minified) and the additional processing required by the browser to read GeoJSON out of the input TopoJSON. So, if you have a small GeoJSON file with a relatively small number of polygons, or the polygon features in that GeoJSON file don’t share borders, it might not make sense to compress it using TopoJSON. If you’re building choropleth maps using more than a few administrative boundaries, though, it almost always makes sense.

Once you have TopoJSON, you’ll need to decode it into GeoJSON to make it useable. Dans ce cas:

precinctsTopo is the JavaScript variable that references the TopoJSON version of the precinct polygons. precinctsTopo.objects.dcprecincts is a GeoJSON GeometryCollection that contains each precinct polygon. Appeler le topojson.feature method will turn that input TopoJSON into GeoJSON.

Now that I had data and associated polygons, I decided to create a couple of visualizations. The first visualization illustrates crimes in DC by voting precinct using a single L.DataLayer instance but provides different visuals based on the input precinct. For some precincts, I decided to display pie charts sized by total crime, and for others I decided to draw a MarkerGroup of stacked CircleMarker instances sized and colored by crime.

The reason for doing this is that I wanted to illustrate two different capabilities that we provide our partners, event detection from social media and geo statistics. Including these in the same DataLayer instance ensures that the statistical data only get parsed once. For the event detection layer, I also wanted to spice it up a bit by adding an L.Graph instance that illustrates the propagation of an event in social media from its starting point to surrounding areas. In this case, I generated some fake data that represent the movement of information between two precincts, where each record is an edge. Here’s what the fake data look like:

Here’s the code for instantiating an L.Graph instance and adding it to the map.

The locations for nodes in the graph are specified via the precincts GeoJSON retrieved from the TopoJSON file I discussed earlier. fromField et toField tell the L.Graph instance how to draw lines between nodes.

The pie charts include random slice values. I could have used the actual data and broken down the crime in DC by type, but I wanted to keep the pie charts simple, and three slices seemed like a good number. There are more than three crime types that were committed in DC in 2013. As a bit of an aside, here’s a representation of crimes in DC color-coded by type using L.StackedRegularPolygonMarker instances.

The code for this visualization can be found in the DVF examples here. It’s more artistic than practical. One of the nice features of the Leaflet DVF is the ability to easily swap visualizations by changing a few parameters – so in this example, I can easily swap between pie charts, bar charts, and other charts just by changing the class that’s used (e.g. L.PieChartDataLayer, L.BarChartDataLayer, etc.) and modifying some of the options.

After I decided what information I wanted to display using pie charts, I ventured over to the Color Brewer website and settled on some colors – the 3 class Accent color scheme in the qualitatif section here – that work well together while fitting in with the pastel color scheme prevalent in the Stamen watercolor background tiles. The Leaflet DVF has built in support for Color Brewer color schemes (using the L.ColorBrewer object), so if you see a color scheme you like on the Color Brewer website, it’s easy to apply it to the map visualization you’re building using the L.CustomColorFunction class, like so:

I also wanted to highlight some of the work we’ve been doing related to mobility analysis, so I repurposed the running data from the Leaflet DVF Run Map example and styled the WeightedPolyline so that it fit in better with our Stamen watercolor map, using a white to purple color scheme. The running data look like this:

Check out the Run Map example to see how this data can be turned into a variable weighted line or the GPX Analyzer example that lets you drag and drop GPS Exchange Format (GPX) files (a common format for capturing GPS waypoint/trip data) onto the map to see variations in the speed of your run/bike/or other trip in space and time.

To make the map a little more interesting, I added some additional layers for our office, employees, and some boats in the water (the employee and boat locations are made up). Now that I had the map layers I wanted to use, I incorporated them into a tour that allows a user to navigate the map like a PowerPoint presentation. I built a simple tour class that has methods for navigating forward and backward. Each tour action consists of an HTML element with some explanatory text and an associated function to execute when that action occurs. In this case, the function to execute usually involves panning/zooming to a different layer on the map or showing/hiding map layers. The details of the tour interaction go beyond collecting, transforming and visualizing geospatial data, so feel free to explore the code here and check out the tour for yourself by visiting our site and clicking on the HumanGeo logo.

We’re hiring! If you’re interested in geospatial, big data, social media analytics, Amazon Web Services (AWS), visualization, and/or the latest UI and server technologies, drop us an e-mail at [email protected]


Lessons learnt

Over the past year we’ve come from knowing practically nothing about 3D rendering and geographic data visualisation, to knowing at least enough about each of them to be dangerous. Along the way we’ve hit many roadblocks and have had to spend a significant amount of time working out what’s wrong and coming up with solutions to get around them.

The process of problem solving is one I absolutely thrive on, but it’s not for everybody and I hope that the lessons I’m about to share will help you avoid these same problems, allowing you to save time and do more important things with your life.

These lessons are in no particular order.

Using a modular, decoupled application architecture pays off in the long run

We originally started out with hacky, prototypal experiments that were dependency heavy and couldn’t easily be pulled apart and used in other experiments. Although it allowed us to learn how everything worked, it was a mess and caused a world of pain when it came to building out a proper application.

In the end we re-wrote everything based on a simple approach using the Constructor Pattern and the prototype property. Using this allowed us to separate out logic into decoupled modules, making everything a bit more understandable whilst also allowing us to extend and replace functionality without breaking anything else (we use the Underscore _.extend method to extend objects).

Here’s an example of our use of the Constructor Pattern.

To communicate amongst modules we use the Mediator Pattern. This allows us to keep things as decoupled as possible as we can publish events without having to know about who is subscribing to them.

Here’s an example of our use of the Mediator Pattern:

I’d argue that these 2 patterns are the most useful aspects of the new ViziCities application architecture &ndash they have allowed us to iterate quickly without fear of breaking everything.

Using promises instead of wrestling with callbacks

Early on in the project I was talking to my friend Hannah Wolfe (Ghost’s CTO) about how annoying callbacks are, particularly when you want to load a bunch of stuff in order. It didn’t take Hannah long to point out how stupid I was being (thanks Hannah) and that I should be using promises instead of wrestling with callbacks. At the time I brushed them off as another hipster fad but in the end she was right (as always) and from that point onwards I used promises wherever possible to take back control of application flow.

For ViziCities we ended up using the Q library, though there are plenty others to choose from (Hannah uses when.js for Ghost).

The general usage is the same whatever library you choose &ndash you set up promises and you deal with them at a later date. However, the beauty comes when you want to queue up a bunch of tasks and either handle them in order, or do something when they’re all complete. We use this in a variety of places, most noticeably when loading ViziCities for the first time (also allowing us to output a progress bar).

I won’t lie, promises take a little while to get your head around but once you do you’ll never look back. I promise (sorry, couldn’t resist).

Using a consistent build process with basic tests

I’ve never been one to care too much about process, code quality, testing, or even making sure things are Done Right&trade. I’m a tinkerer and I much prefer learning and seeing results than spending what feels like wasted time on building a solid process. It turns out my tinkering approach doesn’t work too well for a large Web application which requires consistency and robustness. Qui savait?

The first step for code consistency and quality was to enable strict mode and linting. This meant that the most glaring of errors and inconsistencies were flagged up early on. As an aside, due to our use of the Constructor Pattern we wrapped each module in an anonymous function so we could enable strict mode per module without necessarily enabling it globally.

At this point it was still a faff to use a manual process for creating new builds (generating a single JavaScript file with all the modules and external dependencies) and to serve the examples. The break-through was adopting a proper build system using Grunt, thanks mostly to a chat I had with Jack Franklin about my woes at an event last year (he subsequently gave me his cold which took 8 weeks to get rid of, but it was worth it).

Grunt allows us to run a simple command in the terminal to do things like automatically test, concatenate and minify files ready for release. We also use it to serve the local build and auto-refresh examples if they’re open in a browser. You can look at our Grunt setup to see how we set everything up.

For automated testing we use Mocha, Chai, Sinon.js, Sinon-Chai and PhantomJS. Each of which serves a slightly different purpose in the testing process:

  • Mocha is used for the overall testing framework
  • Chai is used as an assertion library to allows you to write readable tests
  • Sinon.js is used to fake application logic and track behaviour through the testing process
  • PhantomJS is used to run client-side tests in a headless browser from the terminal

We’ve already put together some (admittedly basic) tests and we plan to improve and increase the test coverage before releasing 0.1.0.

Travis CI is used to make sure we don’t break anything when pushing changes to GitHub. It automatically performs linting and runs our tests via Grunt when changes are pushed, including pull requests from other contributors (a life saver). Plus it lets you have a cool badge to put on your GitHub readme that shows everyone whether the current version is building successfully.

Together, these solutions have made ViziCities much more reliable than it has ever been. They also mean that we can move rapidly by building automatically, and they allow us to not have to worry so much about accidentally breaking something. The peace of mind is priceless.

Monitoring performance to measure improvements

General performance in frames-per-second can be monitored using FPSMeter. It’s useful for debugging parts of the application that are locking up the browser or preventing the rendering loop from running at a fast pace.

You can also use the Three.js renderer.info property to monitor what you’re rendering and how it changes over time.

It’s worth keeping an eye on this to make sure objects are not being rendered when they move out of the current viewport. Early on in ViziCities we had a lot of issues with this not happening and the only way to be sure we to monitor these values.

Turning geographic coordinates into 2D pixel coordinates using D3.js

One of the very first problems we encountered was how to turn geographic coordinates (latitude and longitude) into pixel-based coordinates. The math involved to achieve this isn’t simple and it gets even more complicated if you want to consider different geographic projections (trust me, it gets confusing fast).

Fortunately, the D3.js library has already solved these problems for you, specifically within its geo module. Assuming you’ve included D3.js, you can convert coordinates like so:

The scale() value is the hardest part of the process to understand. It basically changes the pixel value that’s returned based on how zoomed in you want to be (imagine zooming in on Google Maps). It took me a very long time to understand so I detailed how scale works in the ViziCities source code for others to learn from (and so I can remember!). Once you nail the scaling then you will be in full control of the geographic-to-pixel conversion process.

Extruding 2D building outlines into 3D objects on-the-fly

While 2D building outlines are easy to find, turning them into 3D objects turned out to be not quite as easy as we imagined. There’s currently no public dataset containing 3D buildings, which is a shame though it makes it more fun to do it yourself.

What we ended up using was the THREE.ExtrudeGeometry object, passing in a reference to an array of pixel points (as a THREE.Shape object) representing a 2D building footprint.

The following is a basic example that would extrude a 2D outline into a 3D object:

What turned out interesting was how it actually turned out quicker to generate 3D objects on-the-fly than to pre-render them and load them in. This was mostly due to the fact it would take longer to download a pre-rendered 3D object than downloading the 2D coordinates string and generating it at runtime.

Using Web Workers to dramatically increase performance and prevent browser lockup

One thing we did notice with the generation of 3D objects was that it locked up the browser, particularly when processing a large number of shapes at the same time (you know, like an entire city). To work around this we delved into the magical world of Web Workers.

Web Workers allow you to run parts of your application in a completely separate processor thread to the browser renderer, meaning anything that happens in the Web Worker thread won’t slow down the browser renderer (ie. it won’t lock up). It’s incredibly powerful but it can also be incredibly complicated to get working as you want it to.

We ended up using the Catiline.js Web Worker library to abstract some of the complexity and allow us to focus on using Web Workers to our advantage, rather than fighting against them. The result is a Web Worker processing script that’s passed 2D coordinate arrays and returns generated 3D objects.

After getting this working we noticed that while the majority of browser lock-ups were eliminated, there were two new lock-ups introduced. Specifically, there was a lock-up when the 2D coordinates were passed into the Web Worker scripts, and another lock-up when the 3D objects were returned back to the main application.

The solution to this problem came from the inspiring mind of Vladimir Agafonkin (of LeafletJS fame). He helped me understand that to avoid the latter of the lock-ups (passing the 3D objects back to the application) I needed to use transferrable objects), namely ArrayBuffer objects. Doing this allows you to effectively transfer ownership of objects created within a Web Worker thread to the main application thread, rather than copying them. We implemented this to great effect, eliminating the second lock-up entirely.

To eliminate the first lock-up (passing 2D coordinates into the Web Worker) we need to take a different approach. The problem lies again with the copying of the data, though in this case you can’t use transferrable objects. The solution instead lies in loading the data into the Web Worker script using the importScripts method. Unfortunately, I’ve not yet worked out a way to do this with dynamic data sourced from XHR requests. Still, this is definitely a solution that would work.

Using simplify.js to reduce the complexity of 2D shapes before rendering

Something we found early on was that complex 2D shapes caused a lot of strain when rendered as 3D objects en-masse. To get around this we use Vladimir Agafonkin’s simplify.js library to reduce the quality of 2D shapes before rendering.

It’s a great little tool that allows you to keep the general shape while dramatically reducing the number of points used, thus reducing its complexity and render cost. By using this method we could render many more objects with little to no change in how the objects look.

Getting accurate heights for buildings is really difficult

One problem we never imagined encountering was getting accurate height information for buildings within a city. While the data does exist, it’s usually unfathomably expensive or requires you to be in education to get discounted access.

The approach we went for uses accurate height data from OpenStreetMap (if available), falling back to a best-guess that uses the building type combined with 2D footprint area. In most cases this will give a far more accurate guess at the height than simply going for a random height (which is how we originally did it).

Restricting camera movement to control performance

The original dream with ViziCities was to visualise an entire city in one go, flying around, looking down on the city from the clouds like some kind of God. We fast learnt that this came at a price, a performance price, and a data-size price. Neither of which we were able to afford.

When we realised this wasn’t going to be possible we looked at how to approach things from a different angle. How can you feel like you’re looking at an entire city without rendering an entire city? The solution was deceptively simple.

By restricting camera movement to only view a small area at a time (limiting zoom and rotation) you’re able to have much more control over how many objects can possibly be in view at one time. For example, if you prevent someone from being able to tilt a camera to look at the horizon then you’ll never need to render every single object between the camera and the edge of your scene.

This simple approach means that you can go absolutely anywhere in the world within ViziCities, whether a thriving metropolis or a country-side retreat, and not have to change the way you handle performance. Every situation is predictable and therefore optimisable.

Tile-based batching of objects to improve loading and rendering performance

Another approach we took to improve performance was by splitting the entire world into a grid system, exactly like how Google and other map providers do things. This allows you to load data in small chunks that eventually build up to a complete image.

In the case of ViziCities, we use the tiles to only request JSON data for the geographic area visible to you. This means that you can start outputting 3D objects as each tile loads rather than waiting for everything to load.

A by-product of this approach is that you get to benefit from frustum culling, which is when objects not within your view are not rendered, dramatically increasing performance.

Caching of loaded data to save on time and resources when viewing the same location

Coupled with the tile-based loading is a caching system that means that you don’t request the same data twice, instead pulling the data from a local store. This saves bandwidth but also saves time as it can take a while to download each JSON tile.

We currently use a dumb local approach that resets the cache on each refresh, but we plan to implement something like localForage to have the cache persist between browser sessions.

Using the OpenStreetMap Overpass API rather than rolling your own PostGIS database

Late into the development of ViziCities we realised that it was unfeasible to continue using our own PostGIS database to store and manipulate geographic data. For one, it would require a huge server just to store the entirety of OpenStreetMap in a database, but really it was just a pain to set up and manage and an external approach was required.

The solution came in the shape of the Overpass API, an external JSON and XML endpoint to OpenStreetMap data. Overpass allows you to send a request for specific OpenStreetMap tags within a bounding box (in our case, a map tile):

And get back a lovely JSON response:

The by-product of this was that you get worldwide support out of the box and benefit from minutely OpenSteetMap updates. Seriously, if you edit or add something to OpenStreetMap (please do) it will show up in ViziCities within minutes.

Limiting the number of concurrent XHR requests

Something we learnt very recently was that spamming the Overpass API endpoint with a tonne of XHR requests at the same time wasn’t particularly good for us nor for Overpass. It generally caused delays as Overpass rate-limited us so data took a long time to make its way back to the browser. The great thing was that by already using promises to manage the XHR requests we were half-way ready to solve the problem.

The final piece of the puzzle is to use throat.js to limit the number of concurrent XHR requests so we can take control and load resources without abusing external APIs. It’s beautifully simple and worked perfectly. No more loading delays!


Tilt of OpenStreetMap with LeafletJs - Geographic Information Systems

لیست استان ها / شهرستان ها و شهر های ایران به همراه مختصات سال 97

منابع مختلفی در اینترنت موجود هست برای دریافت دیتای مرتبط به تقسیمات کشوری ولی خیلی از موارد یا تقسیم بندی کاملی ندارند یا قدیمی هستند یا فرمت مناسبی ندارند.

برای یکی از نرم افزارها نیاز بود لیست به روز (سال 96-97) شهر‌های ایران رو به تفکیک استان/شهرستان/شهر به همراه مختصات آنها برای نمایش روی نقشه به صورت اطلاعات پایه در نرم افزار داشته باشیم. این شد که این فایل رو با توجه به دیتای سایت آمار کشور و چند سایت دیگر جمع آوری کردیم.

در نهایت این لیست رو به فرمت json به اشتراک گذاشتم تا دوستان هم اگر نیازی داشتند استفاده کنند.

دور زدن تحریم جدید گوگل مپ

مثل گوگل مپ ساده نیست اما نقشه‌اش خوب است. تا موقع تعیین تکلیف می‌شود ازش استفاده کرد.

سرویس دهی رایگان Google Maps از فردا خاتمه می‌یابد

Google revamps its Google Maps developer platform

اضافه شدن زبان فارسی به Google Maps

Google Maps learns 39 new languages

کتاب Bing Maps V8 Succinctly

At least 80% of all information being collected by enterprises includes geolocation data. The Bing Maps V8 library is a very large collection of JavaScript code that allows web developers to place a map on a webpage, query for data, and manipulate objects on a map, creating a geo-application. Dans Bing Maps V8 Succinctly, James McCaffrey takes readers through utilizing this library, from creating the simplest application that uses it, to mastering more advanced functions like creating color-gradient legends and custom-styled Infobox objects.

  1. Getting Started
  2. Fundamental Techniques
  3. Working with Data
  4. Advanced Techniques

کتابخانه DotSpatial

DotSpatial is a geographic information system library written for .NET Framework. It allows developers to incorporate spatial data, analysis and mapping functionality into their applications or to contribute GIS extensions to the community.

DotSpatial provides a map control for .NET and several GIS capabilities including:

  • Display a map in a .NET Windows Forms.
  • Open shapefiles, grids, rasters and images.
  • Render symbology and labels.
  • Reproject on the fly.
  • Manipulate and display attribute data.
  • Scientific analysis.
  • Read GPS data.

کتاب Leaflet.js Succinctly برای نمایش نقشه‌های تعاملی

شروع کار با MAP API در برنامه های UWP

Getting started with map APIs and controls

کتابخانه vizicities

3D city and data visualization platform Demo

Libraries and resources used

  • OpenStreetMap – Map data
  • Three.js – WebGL
  • D3.js – Geographic coordinate conversion
  • Underscore.js – General helpers
  • Q – Promises
  • Throat - Limiting concurrency
  • Catiline – Web Workers
  • Dat.gui – Debug control panel
  • FPSMeter – FPS meter
  • Moment.js – Date processing
  • Simplify.js – Polygon simplification
  • Grunt – Build system

13 کتابخانه جاوااسکریپتی برای ساخت نقشه های اختصاصی و تعامل گرا

کتابخانه useful-photomap

نقشه ایران با highmaps

نقشه ایران رو که توسط پلاگین HighMaps تولید میشه بهینه کردم و تو آدرس بالا گذاشتم.

پروژه Natural Earth Vector

Free vector and raster map data

A global, public domain map dataset available at three scales and featuring tightly integrated vector and raster data
Natural Earth v2.0.0 release notes

نقشه های رویداد پذیر Asp.net + SVG

This article explains step-by-step the server-side manipulation of SVG using Microsoft ASP.NET and C#. The example server-side application demonstrates how simple and complex maps can easily be represented using SVGs.

فریمورک جاوا اسکریپتی Highmaps

www.highcharts.com شروع کار با Highmaps

GMap.NET - استفاده از نقشه های بزرگ در پروژه های ویندوز

کتابخانه منبع باز جهت ساخت نقشه‌های تعاملی


4 TECHNICAL VALIDATION: RELIABLE USE OF DATA IN ANALYSIS

4.1 Map preparation

In the 1930s, in warfare conditions, topographic maps were produced very rapidly from the aerial photographs by IGM's 7th Topocartographic Section, a unit that was equipped with extensive photographic, photo-mechanical and printing facilities, located in Asmara (Nyssen et al., 2016 ). These initial maps were mainly planimetric: topographic characteristics were added by rough contour lines to show the relative heights, the shape and the character of the landforms (Nyssen et al., 2019 ). Later on, accurate maps were produced for the same areas at 1:50,000 and 1:100,000 scales (IGM, 1939 ). The scanned versions are available at the Istituto Geografico Militare Italiano (http://www.igmi.org/ancient/).

4.2 Qualitative and quantitative studies

A few representative examples of the use of these historical APs include qualitative geomorphic analyses. In the 1930s, the APs were used to study the structural geomorphology of Tigray (Merla & Minucci, 1938 ) and more recently the long-term dynamics of mountain streams (Ghebreyohannes et al., 2015 ). The APs were also successfully used in a study on historical road engineering geology in the Blue Nile gorge (Hearn, 2019 ).

Qualitative studies of land cover change (Frankl, 2012 Hishe et al., 2020 ) and land tenure in feudal times (Lanckriet et al., 2015 Nyssen & Denaeyer, 2019 ) have also been carried out using these APs, as well as interpretations of changes to the level of Lake Hayq and urban expansion of Mekelle since the 1930s (Nyssen et al., 2016 ).

Quantitative change studies were carried out using the point-count method (Bellhouse, 1981 Zeimetz et al., 1976 ), hence without orthorectification concerned, particularly in relation to changes in land use (Guyassa et al., 2018b ) in the Giba basin in Tigray. In the same area, densities of gully and SWC networks were measured by counting the number of features on transversal transect lines (Guyassa et al., 2018a ).

4.3 Georeferencing and orthorectification methods and spatially explicit studies

First to third order polynomial transformation using tie points (Hughes et al., 2006 ), also called rubbersheeting or spline, was used to orthorectify the APs and carry out diachronic analysis of land-use changes on the western Rift Valley escarpment (Ghebreyohannes et al., 2018 ), north of Dessie (Kassa et al., 2011 ), around church forests (Scull et al., 2017 ) and at Mt. Guna's treeline (Jacob, 2015 ). Landsliding was investigated in Dessie, using APs that were processed in the same way (Kropáček et al., 2019 ).

A further step has been the reconstruction of ortho-mosaics and preparation of 3D models of the historical landscapes. We built upon the combination of Structure-from-Motion (SfM) and MultiView Stereo (MVS) (Frankl et al., 2015b James & Robson, 2012 ) to construct ortho-mosaics and 3D models from aerial photographs. The SfM part makes it possible to reconstruct an area based on an unordered collection of images. By detecting and matching textures in the photographs, they can be matched to each other. The algorithms calculate the camera parameters and the orientation of every picture. Particularly, SfM allows reconstructing the three-dimensional scene geometry and the position of the cameras during the image acquisition period of the images captured around a scene or a landscape, even when imagery is already degraded or when the imagery lacks calibration information (Sevara et al., 2018 ). SfM allows this without using prior topographic data (Peterson, 2017 ).

To execute the process of SfM-MVS, the most common software PhotoScan, distributed by Agisoft, was used, which extends SfM with MVS. The method was successfully applied in small areas in Tigray (Frankl et al., 2015a ) and in the Lake Tana basin (Frankl et al., 2019 ), using vertical and low-oblique frames, all manually cropped to single images.

The method was further developed for wider areas. The scanned photosets do not only contain the scene of interest (SOI), but are assemblages of four frames. The photographs each contain black borders strips of the hardboard on which the photographs are glued are also visible on the scans. The scanned photosets were automatically cropped, divided into the individual frames (Appendix E) and contrast stretched using python scripts allowing batch processing. As the frames had been cropped before gluing on hardboard, there is no overlap between the vertical and low-oblique APs within the photosets, hence a lack of tie points between the frames which can hinder the correct alignment of the APs in a single geometrical model in the SfM processing. To overcome this problem, the subsets are slightly larger than the AP frames to include also a narrow stripe of the adjacent APs which served as a ‘false overlap’. This results in a number of model points in the overlaps between the AP from the same photoset (Figure 7). This approach improved the alignment of the APs but as a drawback it may lead to a lower geometrical accuracy of the model resulting in the occurrence of irregular shapes and gaps in the resulting ortho-mosaic (Forceville, 2018 ).

A dense point cloud was then built, using the calculated camera positions from the alignment step, from which it calculated depth information for each camera location. Through combination, a single dense point cloud was obtained (Figure 8), which was used as a more detailed and accurate input for the generation of Meshes, Digital Elevation Model (DEM) and the Tiled Model (Agisoft, 2018 ).

For the construction of a dense point cloud, we set the ‘quality’ to Ultra High, meaning that the processing was carried out with the original resolution of the photographs. Lower quality parameters result in processing results based on downscaled image sizes. The ‘Depth filtering mode’ was set to Aggressive for each time period (Debever, 2019 ), as recommended by Agisoft PhotoScan.

Next, a polygonal model – a so-called mesh – was generated, which served as final input for the generation of the ortho-mosaics. As we processed the frames, the mesh processing parameter ‘surface type’ was set to ‘Height field’. The necessary camera parameters (Seitz et al., 2006 ) were computed through SfM, and a spatial resolution of 0.50 m was achieved.

Bien que Agisoft Photoscan offers the possibility to georeference the ortho-mosaics during the process of ortho-mosaicking by adding ground control points (GCPs) after the alignment step, the option of georeferencing the ortho-mosaics in ArcMAP was preferred. An investigation of the optimal number of GCPs to be added to the mosaicking process in Agisoft Photoscan showed that with an increasing amount of GCPs, the RMSE in X and Y stagnated to an error of approximately 30 m.

As the bearing and tilt information could, unfortunately, not yet be recovered and besides this, the scanners that were used for the scanning operations of the APs could not be calibrated in order to minimize distortions caused by the scanner (Nyssen et al., 2016 ), a spline transformation was used to georeference the ortho-mosaics using numerous GCPs (www.pro.arcgis.com).

On a sample data set, the accuracy was measured by calculating the difference between the X-coordinates (dX) and the Y-coordinates (dY) from a checkpoint on the georeferenced data set – this is a point on the data set that was not used as GCP – and its equivalent in the current landscape. The checkpoints were chosen by means of a regular grid with 1,500 m between nodes. An estimation of the error in X and Y was then interpolated by means of the kernel density tool in ArcMAP. Errors in the data sets 1935–36 were less than 30 m in Oui and less than 15 m in X (Figure 9) (Debever, 2019 ).

Errors could be related to the non-uniform scale and geometry of the photographs (particularly for the low-oblique frames in mountain areas) or to random errors during the localization of ground control points. None of the georeferenced data sets show high systematic errors, but some areas have a clearly higher error than the others. The extent of the ortho-mosaics was determined by the quality of the scanned aerial photographs and the number of overlapping APs (Figure 10). Poor quality of some frames is for instance related to local differences in contrast, moisture-induced damage of photographs or presence of clouds. An alternative approach could be to work with less GCPs, generate an error map and then add GCPs in the areas with greatest errors (Persia et al., 2020 ).

Manually cropped subsets, without creating false overlaps, have generally good orthophotographs with only occasionally an artefact or a gap. However, because of a lack of overlap between the vertical photographs and their adjacent low-oblique photographs, in most cases only one camera line is matched.

When the automatically cropped aerial photographs were processed in PhotoScan, they had a clearly different output. First of all, there were significantly more photographs matched. This is due to the false overlap between low-oblique and vertical photographs. Many of the resulting orthophotographs have however irregular shapes and gaps, and brown lines, parts of the hardboard tiles on which the photographs were glued, appearing between photographs along the flight line. Rather than processing all photographs of one flight line with the same parameters, they would need to be visually inspected and grouped, so that cropping occurs with adjusted parameters (Forceville, 2018 ). Recent expertise indicates that the implementation of GCPs and terrain heights (Pinto et al., 2019 ) could help in the orthorectification, while taking into account incomplete metadata (James et al., 2019 ).

4.4 Further relocation of photosets

The APs do not at all cover the full country, and the number of photosets is far too small. Besides, within flights some photographs could not be recovered. A major issue is that so far, we failed relocating 5,149 photosets based on merely a few place names in a wider area, particularly those without readily recognizable features. Hence, a semi-automated method to localize and scale these aerial photographs has been tested (Walter & Fritsch, 1999 ). At first, within an unlocated series of successive photosets, the photographs were aligned to create an ortho-mosaic, and DEM extracted (when sufficient overlap between adjacent photos). The result was used to extract the drainage network of that unknown area (Ariza-Villaverde et al., 2015 ). Next, similarities were searched with parts of the recent drainage network (extracted from the SRTM30). This comparison was performed by a script to detect matches (Hussnain et al., 2016 Mustière & Devogele, 2008 ). The algorithm was based on Strahler's stream orders of the rivers (Luo et al., 2014 Molloy & Stepinski, 2007 ), the angle difference between the historical an recent segments (Borgefors, 1988 ) and the scale between both networks (Forceville, 2018 ).

Though the method was successful on regular imagery taken in 1964, the Italian imagery from the 1930s over Ethiopia could not be relocated through it. Indeed, the algorithm performs best with high stream orders and a long array of consecutive streams, but these were difficult to obtain from the chunks of flight lines available for the studied photosets. Another problem was that incorrect drainage networks were generated because of gaps in the generated DEM and artefacts induced by the borders of the frames (Forceville, 2018 ).

The best option that remains is manual tracing using Google Earth or similar, possibly as geo-crowdsourcing (Porto De Albuquerque et al., 2016 Produit & Ingensand, 2018 ), in which interested people try to locate photosets from flights in selected approximate coverage areas (Figure 11).

4.5 Automated aerial photograph interpretation

These historical aerial photographs offer a great opportunity to prolong the timespan over which land cover data, and studies have been undertaken to understand the complexity of land cover changes in a more accurate way (see above). Yet, analogous interpretation of black and white orthophotographs is very time-consuming. The possibilities of such historical aerial imagery for the (semi-) automated extraction of the land cover classes ‘cropland’ and ‘woody vegetation’ were investigated. A subset of the APs was analysed within the study area covering 323 km 2 in the eastern part of the Dogu'a Tembien district in the Tigray region (Figure 1). For the classification of cropland, we applied the combination (Vogels et al., 2017 ) of object-based classification technique and random forest machine learning technique (Breiman, 2001 Liaw & Wiener, 2002 ), of which the classification results achieved a Kappa coefficient (Lillesand et al., 2008 ) between 0.40 and 0.70. From the 22 different object variables that were taken into account during the classification process, textural variables based on the grey-level co-occurrence matrix seemed to play a more important role during the classification process than geometrical variables and the brightness of the objects (Debever, 2019 ).

In view of the large number of possible objects in areas with woody vegetation, it was preferred to use a pixel-based classification technique for the ‘woody vegetation’ that was anticipated to appear with a lower brightness (Kadmon & Harari-Kremer, 1999 Sharp & Bowman, 2004 ). At first, this led to an overestimation of the amount of ‘woody vegetation’. Whereas such errors would be corrected through manual editing in case of smaller areas (Frankl et al., 2019 ), pour Tembien, les résultats ont été optimisés au moyen d'un processus intégrant les approches basées sur les pixels et les objets (Debever, 2019 ). Ces PA historiques offrent de nombreuses perspectives pour analyser et modéliser les changements d'occupation des sols en Éthiopie, mais il existe des défis liés à une qualité parfois moindre des PA.


Vendredi 07 mai 2021

Comment vos voisins ont voté

L'Amérique est un pays politiquement divisé. Cette division est peut-être plus apparente dans l'endroit où nous vivons. La plupart des Américains vivent dans des quartiers peuplés de personnes ayant des opinions politiques très similaires. Vous pouvez savoir si vous vivez dans une bulle politique dans le New York Times' Vivez-vous dans une bulle politique .

Entrez votre adresse dans la visualisation de données interactive du NYT et vous pouvez afficher une carte à points montrant comment vos milliers de voisins les plus proches ont voté lors des élections américaines de 2020. Continuez à faire défiler et la visualisation vous indiquera le pourcentage de vos voisins qui ont voté pour le parti le moins populaire.

Vous pouvez ou non vivre dans une bulle politique, mais de nombreux Américains faire vivent dans des quartiers très partisans de leur politique. Alors que vous continuez à faire défiler Do You Live in a Political Bubble du NYT, des cartes des régions les plus démocratiques (Bay Area) et républicaines (Gillette, Wyo) du pays s'affichent. Selon le NYT, environ un républicain sur cinq et deux démocrates sur cinq vivent dans des quartiers où plus de 75 % de leurs voisins partagent leur affiliation politique.


Voir la vidéo: Mapping Database Entries with - Working with Data and APIs in JavaScript