Existe-t-il une bibliothèque Python pour demander WMS / WFS et enregistrer en tant qu'image / PDF?

18

Je me demande s'il y a une bibliothèque GIS open source Python qui a des API pour prendre en charge les appels WMS / WFS à partir d'un autre serveur SIG (par exemple, GeoServer), puis enregistrer les données de réponse (WMS Basemap et couche WFS) sous forme d'images.

des recommandations?

merci pour toutes les entrées!

MISE À JOUR :

ce que j'essaie de faire, c'est un service d'impression de cartes, en utilisant OpenLayers comme frontal et Django comme serveur; L'utilisateur client définit l'étendue et les couches, puis envoie la demande d'impression (qui fait référence aux paramètres, c'est-à-dire l'étendue de la carte, les noms des couches) au serveur, puis le serveur reprend cette demande et appelle à nouveau WMS / WFS en utilisant les paramètres de demande, enregistrez la réponse au format PDF, exportez ce lien PDF vers le client.

La partie difficile est que la façon dont le serveur appelle WMS / WFS et combine / superpose ces réponses (c'est-à-dire, assemble ces cartes / couches, puisque WMS est généralement la carte de base, WFS pointe vers les couches d'entités), enfin, enregistrez cet objet combiné comme image.

dans les réponses actuelles, urllib semble bon, mais je ne sais pas comment combiner ces réponses (WMS, WFS) ensemble; OWSLib semble également une autre bonne option, mais cela indique que c'est un outil de programmation client, je suis un peu confus que ce soit approprié pour mon utilisation ...

toute autre entrée supplémentaire ???

apprécier!

Simon
la source
Je ne pense pas qu'il y en ait, mais c'est une bonne idée!
OptimizePrime
Je viens de remarquer que la question mise à jour est liée à ma question sur la combinaison de WMS en PDF.
MarkJ

Réponses:

18

Il y a OWSLib qui devrait fournir exactement ce dont vous avez besoin.

OWSLib est un package Python pour la programmation client avec les normes d'interface de service Web Open Geospatial Consortium (OGC) (d'où OWS) et leurs modèles de contenu associés.

OWSLib fournit une API commune pour accéder aux métadonnées et wrappers de service pour de nombreuses interfaces de service Web OGC.

Documentation et exemples ici . Dans ce contexte, le client signifie qu'il s'agit d'une application client vers un serveur WMS / WFS - elle peut être exécutée sur un serveur si nécessaire.

Après avoir ajouté plus de détails à votre réponse, il semble que l'application d'impression MapFish correspond exactement à vos besoins. Il s'agit d'une application Java qui peut être intégrée avec OpenLayers et assembler des tuiles, WMS, WFS, etc. et produire un PDF.

Comme il s'agit d'une application en ligne de commande, elle peut être manipulée avec un wrapper Python. Voir les liens suivants pour plus de détails:

http://geographika.co.uk/mapfish-print-module-for-iis

https://github.com/amercader/MapFish-Print-IIS

geographika
la source
1
Merci pour le pointeur sur OWSLib, je n'en avais jamais entendu parler.
user2856
7

Vous pouvez utiliser la bibliothèque python urllib pour appeler directement un WMS et écrire la réponse dans un fichier. Il y a un bon exemple d'utilisation d'urllib dans cette réponse . Remplacez simplement l'URL par une pour un WMS, par exemple http: //some.wms.service? Request = GetMap & VERSION = 1.1.1 & BBOX = 141.00, -29.00,141.80, -28.40 & SRS = EPSG: 4326 & LAYERS = LANDSAT_MOSAIC & WIDTH = 800 & HEIGHT = 600 & FORMAT = image / png .

Vous pouvez également utiliser la bibliothèque GDAL pour accéder à WMS ( http://www.gdal.org/frmt_wms.html ) et la bibliothèque OGR pour accéder à WFS ( http://www.gdal.org/ogr/drv_wfs.html )

Si vous souhaitez créer une image du WFS, vous pouvez utiliser la fonction gdal.RasterizeLayer pour créer un jpg. Il y a un exemple ici .

user2856
la source
2

Voici un exemple simple. Côté serveur:

def get_wfs():
    '''
    Get data from wfs server. Example url is:
    http://192.168.0.1:8080/geoserver/wfs?request=GetFeature&version=1.0.0&service=WFS&typeName=ChistaWS:Chista_new_POIs&maxfeatures=20&srsname=EPSG:4326&outputFormat=json
    We can add CQL filter like this:
    CQL_FILTER=name LIKE 'A%25'
    or
    CQL_FILTER=type=1913

    '''
    cql = ''
    if request.vars.cql:
        cql = urllib.quote_plus(request.vars.cql)
    req = 'GetFeature' # request
    version = '1.0.0'
    service = 'WFS'
    typeName = 'Test:Test_Places'
    maxfeatures = 200000
    if request.vars.mf:
        maxfeatures = request.vars.mf
    srsname = 'EPSG:4326'
    outputFormat = 'json'   
    # format_options = 'callback:getLayerFeatures_MY'
    wfs_url = '%s?request=%s&version=%s&service=%s&typeName=%s&maxfeatures=%s&srsname=%s&outputFormat=%s' % \
                (wfs_server, req, version, service, typeName,\
                 maxfeatures, srsname, outputFormat)
    if cql:
        # print cql
        wfs_url += '&CQL_FILTER=%s'%cql
    # print wfs_url
    try:
        jsonp = urllib2.urlopen(wfs_url).read()  # Get the raw server data
    except urllib2.HTTPError:
        return 'WFS Server <a target="_new" href="%s">%s</a> is down!' % (wfs_server, wfs_server)
    # return jsonp
    # try:
        # apijson = jsonp[ jsonp.index("(") + 1 : jsonp.rindex(")") ]
    # except ValueError:
    apijson = jsonp
    try:
        data = sj.loads(apijson)
    except sj.JSONDecodeError:
        return 'Can not parse data. No JSON! here is the data: <pre>%s</pre>' % apijson
    # return data
    features =[{
            'name':i['properties']['name'],
            'type':i['properties']['type'],
            'coordinates':i['geometry']['coordinates'],
            } for i in data['features']]
    # features =[i for i in data['features']]
    # return dict(features=features)
    return {'result':features, 'length':len(features)}

Et côté client en utilisant jquery:

$.ajax({
dataType : 'json',
url: wfsurl,
success  : function (response) {
if (response.length>0){
$('#'+subitem).empty();
for (var i = 0, len = response.length; i < len; i++) {
name = response.result[i].name;
lng = response.result[i].coordinates[0];
lat = response.result[i].coordinates[1];
// console.log(name, lng, lat)
html = '<li class="li-subitem"><a onclick="lazyview($(this));" lat="'+lat+'" lng="'+lng+'">'+name+'</a></li>';
$('#'+subitem).append(html);
}}
else{
$('#'+subitem).toggle(100);
}}});
Farsheed
la source
0

Vous pouvez utiliser GeoTools pour extraire les données des serveurs WMS / WFS et les rendre dans un objet graphique Java. Ensuite, quelque chose comme iText peut être converti en pdf.

Si vous devez vraiment utiliser Python, je m'attends à ce que vous puissiez utiliser un wrapper pour tout gérer.

Ian Turton
la source
1
Merci. mais je veux juste utiliser Python ...
Simon