Comment dégrader intelligemment ou des données SIG lisse (simplification des polygones)?
Question
J'ai des cartes détaillées de comté des États-Unis, des ensembles de données href="http://www.census.gov/geo/www/tiger/" rel="noreferrer"> TIGER LINE. Comment pourrais-je l'échantillon, lisse ou dégrader les données pour que je sois plus droit, plus en forme de boîte, moins formes « bruyants » pour représenter les caractéristiques géographiques - dans ce cas seulement les limites des comtés et des lignes de l'État, mais peut-être aussi dans le cas général?
L'échantillonnage pourrait se produire au moment du rendu si cela peut être fait efficacement, ou un ensemble de données en parallèle pourraient être générées et stockées. J'utilise PostGIS , et les lignes sont multi-polylignes générés par shp2pgsql
- mais toute solution où vous prenez un squiggly ligne et réduire à une ligne plus lisse d'à peu près la même signification à un interprète humain serait très utile.
La solution
Le problème avec tout simplement jeter des points est que vous pouvez déformer rapidement la forme du polygone d'origine. Une meilleure approche est de venir à elle de l'autre direction; commencer par une approximation de base du polygone, puis affiner vers le haut vers votre forme complexe.
Un excellent exemple de cette approche est le algorithme Douglas-Puecker . Vous commencez avec deux sommets tirés du polygone complet. Ajouter un troisième sommet en sélectionnant celle qui se trouve le plus éloigné d'un bord tracée entre les deux premiers sommets. Continuez à ajouter des points jusqu'à ce que vous avez quelque chose qui ressemble suffisamment polygone d'origine.
Autres conseils
Douglas-Peucker est certainement la bonne approche. Il existe des moyens simples d'accéder à des implémentations de celui-ci dans PostGIS et QGIS que je pensais que je voudrais ajouter ici pour ceux qui viennent sur ce poste avec une question similaire. L'objectif est de commencer par quelque chose comme ceci:
et finissent avec quelque chose comme ceci:
Dans PostGIS Douglas-Peucker est implémenté comme simplify
, la syntaxe, rel="noreferrer"> détaillée , est une variante de:
SELECT transform(simplify(transform(the_geom, 2249), 500),4326) from the_geo_table
Cela a fonctionné très bien même sur l'ensemble de données nationale complète, avec quelques peu d'erreurs qui semblent en raison de mauvaises données sous-jacentes. Il se également que dans QGIS l'élément de menu Tools > Geometry Tools > Simplify Geometries
exportera une shapefile simplifiée de toute géométrie et l'ajouter en tant que couche à votre projet actuel.
est un outil mis assez fondamental et je pose la question à un niveau trop bas, mais il était agréable d'apprendre les mathématiques sous-jacente, il y a une bonne explication de cette
Au lieu de QGIS, je suggère d'utiliser ogr2ogr parce que ne supprime pas les polygones ! ogr2ogr output.shp input.shp -simplify 0.0001
Voici un simple algorithme de lissage itératif:
pour chaque trois points successifs sur tout trajet, si le point milieu a aucune intersection et se situe dans un petit angle de seuil de la voie directe entre les deux points extérieurs, le retirer.
Répéter jusqu'à satisfaction.
Vous pouvez également essayer l'algorithme de Visvalingam, qui élimine itérativement la partie la moins sensible d'une ligne. Voici une bonne explication de cet algorithme:
Vous pouvez également utiliser Simplify.js qui utilise une combinaison de Douglas-Peucker et algorithmes Radial Distance. Il y a aussi des liens vers de nombreux ports vers d'autres langues répertoriées sur le github projet
Réponse @unmounted est correcte, mais je voudrais ajouter une suggestion.
Utilisez toujours la fonction ST_SimplifyPreserveTopology au lieu de ST_Simplify dans PostGIS. Les deux utilisent le même algorithme sous-jacent (Douglas-Peucker), mais l'ancien évite des facilitations qui conduiraient à des géométries non valides. Par exemple, ST_Simplify peut entraîner une géométrie qui se croise.