Fichier de formes PRJ vers la table de recherche SRID PostGIS?

38

Je me demandais s'il existe une telle chose comme une table de consultation PRJ vers PostGIS SRID de fichier de formes? Quelque chose qui peut traduire les définitions PRJ de fichier de formes les plus standard en SRID probable.

Lorsque vous utilisez PostGIS et pgAdminIII, si vous utilisez postgisgui pour importer vos fichiers de formes, le SRID est laissé sous la forme "-1". Il semble que l'outil devrait pouvoir analyser le fichier PRJ Esri et déterminer le correct (ou au moins deux options) correspondant au SRID probable, plutôt que de simplement laisser le paramètre par défaut.

Ou bien l’importateur a-t-il la capacité de reprojeter à la volée si vous choisissez un autre SRID?

Cela peut sembler paresseux de ma part, mais il me semble curieux que cette fonction n’ait pas déjà été mise en place. Est-ce que quelqu'un sait si ce concept est en préparation, ou est-ce une bonne raison pour laquelle il a été laissé de côté?

RyanDalton
la source

Réponses:

9

Reprenant l’idée de @iant, voici un module PL / Python3 qui recherchera les codes entiers EPSG SRID d’un fichier PRJ à l’aide du service Web http://prj2epsg.org .

Tout d'abord, installez PL / Python3:

CREATE LANGUAGE plpython3u;

ajoutez maintenant la fonction SQL, qui contient du code écrit pour Python 3:

CREATE OR REPLACE FUNCTION prj2epsg(prj_file text) RETURNS integer AS
$BODY$

import json
from urllib.parse import urlencode
from urllib.request import urlopen

with open(prj_file, 'r') as fp:
    prj_txt = fp.read()

query = urlencode({
    'exact': True,
    'error': True,
    'mode': 'wkt',
    'terms': prj_txt})

webres = urlopen('http://prj2epsg.org/search.json', query.encode())
jres = json.loads(webres.read().decode())

return int(jres['codes'][0]['code'])

$BODY$ LANGUAGE plpython3u VOLATILE COST 100;

Pour l'utiliser depuis PostgreSQL:

SELECT prj2epsg(E'C:\\Temp\\countries.prj');

renvoie 4326 pour mon fichier de test.

Mike T
la source
Je vais marquer cela comme la solution. Alors que les autres sont tous excellents, j'adore cette idée. Maintenant, si nous pouvons simplement demander à une personne disposant de la capacité de codage d’inclure ce type de fonctionnalité dans le chargeur de fichiers de formes PostGIS pgAdmin afin qu’il détermine automatiquement le SRID correct lors de la lecture du SHP. Je vais garder mes doigts croisés.
RyanDalton
1
Les mises en garde sont bien sûr que cela nécessite une connexion Internet et dépend d’un service Web externe qui doit être opérationnel.
Mike T
57

GDAL a une interface pratique et agréable avec la bibliothèque PROJ4.

Si vous avez confiance en Python, si vous importez les classes osr, vous utiliserez les liaisons GDAL Python pour disposer de méthodes très pratiques pour lire et exporter des représentations de projection dans divers formats, tels que PROJ4, WKT, Esri .PRJ.

Par exemple, ce script convertira votre fichier .PRJ de votre fichier de formes en WKT et PROJ4 (le dernier est utilisé par PostGIS):

#! /usr/bin/env python

import sys
from osgeo import osr

def esriprj2standards(shapeprj_path):
   prj_file = open(shapeprj_path, 'r')
   prj_txt = prj_file.read()
   srs = osr.SpatialReference()
   srs.ImportFromESRI([prj_txt])
   print 'Shape prj is: %s' % prj_txt
   print 'WKT is: %s' % srs.ExportToWkt()
   print 'Proj4 is: %s' % srs.ExportToProj4()
   srs.AutoIdentifyEPSG()
   print 'EPSG is: %s' % srs.GetAuthorityCode(None)

esriprj2standards(sys.argv[1])

Exécutez ceci sur la ligne de commande:

$ python esriprj2standards.py /home/pcorti/data/shapefile/country.prj 
Shape prj is: GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
WKT is: GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
Proj4 is: +proj=longlat +datum=WGS84 +no_defs 
EPSG is: 4326
capooti
la source
Cette approche m'a posé deux problèmes: (1) il +proj=longlat +datum=WGS84 +no_defsne figure pas dans le spatial_ref_systableau; vous ne pouvez donc pas utiliser la sortie pour rechercher le SRID; et (2) je n'arrive pas à trouver une propriété ou une méthode SRID (il existe une ImportFromEPSG(SRID)méthode pratique , mais pas l'inverse)
Mike T
4
J'ai mis à jour le script avec un appel à la méthode AutoIdentifyEPSG () qui fera la magie;)
capooti
Très sympa. Excellent travail!
RyanDalton
Quand gdalsrsinfoet ogrinfovous échouez, c'est la voie à suivre!
kontextify
Notez que vous srs.GetAuthorityCode(None)pouvez toujours renvoyer aucun si aucun SRID proche n'a été identifié.
astrojuanlu
19

Cela fait longtemps que je n’utilise pas les srids POSTGIS, mais s’ils ne sont que des codes EPSG, vous pouvez utiliser http://prj2epsg.org/search pour les rechercher à partir de fichiers ESRI.prj (endommagés).

Ian Turton
la source
C'est un site vraiment intelligent. En regardant l' API , vous pourriez écrire un beau script côté serveur pour automatiser la procédure.
Mike T
4

En tant que mélange de solutions, j'ai créé un script pour m'aider à charger des fichiers de formes arbitraires dans postgis. Il essaie également de détecter le codage du DBF.

from chardet.universaldetector import UniversalDetector
import os.path
import sys
import dbfUtils
import sys
from osgeo import osr
from urllib import urlencode
from urllib2 import urlopen
import json

shp_file = sys.argv[1]
dbf_file = shp_file[0:-4] + '.dbf'
prj_file = shp_file[0:-4] + '.prj'

#Try detecting the SRID, by default we set to 4326 and hope the best
srid=4326
if os.path.isfile(prj_file):
    prj_filef = open(prj_file, 'r')
    prj_txt = prj_filef.read()
    prj_filef.close()
    srs = osr.SpatialReference()
    srs.ImportFromESRI([prj_txt])
    srs.AutoIdentifyEPSG()
    code = srs.GetAuthorityCode(None)
    if code:
        srid= code
    else:
        #Ok, no luck, lets try with the OpenGeo service
        query = urlencode({
            'exact' : True,
            'error' : True,
            'mode' : 'wkt',
            'terms' : prj_txt})
        webres = urlopen('http://prj2epsg.org/search.json', query)
        jres = json.loads(webres.read())
        if jres['codes']:
            srid = int(jres['codes'][0]['code'])

#Try to detect the encoding
dbf = open(dbf_file, 'rb')
db = dbfUtils.dbfreader(dbf)

detector = UniversalDetector()
for row in db:
    detector.feed(str(row))
    if detector.done: break
detector.close()
dbf.close()

encoding = detector.result["encoding"]
if encoding=="ascii":
    encoding="LATIN1"

print "shp2pgsql -s %s -k -i -I -W %s %s.shp public.importing_table" %(srid,encoding,shp_file)
Jatorre
la source
3

srsly. J'en veux un aussi.

Beaucoup de gens semblent les rechercher sur http://spatialreference.org

Lorsque vous importez des fichiers de formes à l'aide de PostGIS (et du chargeur PostGIS pour PGAdmin), il recherche les informations sur les projets dans une table appelée spatial_ref_sys.

D'après ce que j'ai compris, la table standard spatial_ref_sys fournie avec PostGIS n'inclut que les représentations OGC WKT (texte bien connu du consortium géospatial ouvert) de certains systèmes de référence spatiaux et PAS des systèmes de référence spatiaux ESRI.

Depuis la documentation de PostGIS 1.5.2:>

La table spatial_ref_sys est une table de base de données conforme à OGC, incluse dans PostGIS, qui répertorie plus de 3001 systèmes de référence spatiale connus et les détails nécessaires pour transformer / reprojeter entre eux.

Bien que la table spatial_ref_sys de PostGIS contienne plus de 3 000 des définitions de système de référence spatiale les plus couramment utilisées pouvant être gérées par la bibliothèque proj, elle ne contient pas toutes les informations connues de man et vous pouvez même définir votre propre projection personnalisée si vous connaissez bien les constructions proj4. . Gardez à l'esprit que la plupart des systèmes de référence spatiale sont régionaux et n'ont aucune signification lorsqu'ils sont utilisés en dehors des limites auxquelles ils étaient destinés.

Une des meilleures ressources pour trouver des systèmes de référence spatiale non définis dans le jeu de base est http://spatialreference.org/ Certains des systèmes de référence spatiale les plus couramment utilisés sont: 4326 - WGS 84 Long Lat, 4269 - NAD 83 Long Lat, 3395 - WGS 84 World Mercator, 2163 - Zone égale de l’Atlas national des États-Unis, référentiels spatiaux pour chaque zone NAD 83, WGS 84 UGS - Les zones UTM sont l’un des meilleurs choix pour la mesure, mais ne couvrent que les régions à 6 degrés.

Divers systèmes de référence spatiale des plans d’États américains (en mètres ou en pieds) - il en existe généralement un ou deux par État américain. La plupart des compteurs sont dans le jeu de base, mais beaucoup de ceux basés sur les pieds ou ceux créés par ESRI que vous devrez extraire de spatialreference.org.

Cependant, ogr2ogr contient des systèmes de référence spatiale ESRI, comme je l’ai récemment appris grâce à la générosité des autres.

Dans ogr2ogr et spatial_ref_sys, il semble que le texte contenu dans le fichier .proj soit comparé à une table de OGC WKT, qui est un format de texte légèrement différent du format ESRI WKT que vous trouvez souvent dans un fichier .proj. De plus, je ne suis pas sûr de savoir comment PostGIS examine chaque SRS, mais les petites différences entre ESRI WKT et OGC WKT pourraient aboutir à des échecs de correspondance.

Il semble simple d'attacher des systèmes de référence spatiale ESRI à la table spatiale par défaut de spatial_ref_sys dans PostGIS. Peut-être que quelqu'un l'a déjà fait, avec un patch ou un script.

Je peux me tromper, car cela fait quelques jours que je me heurte à cela et que je suis frustré par la même chose. Peut-être que quelqu'un d'autre connaît une excellente ressource?

BenjaminGolder
la source
1

Cela faisait longtemps que je n'avais pas besoin, mais, si je me souviens bien, http://spatialreference.org/, en plus de vous permettre de rechercher, vous offre également la possibilité de télécharger un fichier prj.

Ensuite, l’une des options de sortie vous donnera l’insertion postgis équivalente à insérer dans la table spatial_ref_sys.

Pour l'instruction insert qu'il donne, je remplace le srid généré qu'il crée par celui EPSG ou ESRI. Si vous obtenez une violation de clé primaire, vous savez probablement qu'elle est déjà dans la table.

LR1234567
la source