Gibt es eine Python-Bibliothek, um WMS / WFS anzufordern und als Bild / PDF zu speichern?

18

Ich frage mich, ob es Python Open-Source-GIS-Bibliothek gibt, die APIs zum Aufrufen von WMS / WFS von einem anderen GIS-Server (z. B. GeoServer) unterstützt und dann die Antwortdaten (WMS-Grundkarte und WFS-Ebene) als Bilder speichert.

irgendwelche Empfehlungen?

danke für eventuelle eingaben!

UPDATE :

Was ich versuche, ist ein Kartendruckdienst, bei dem OpenLayers als Front-End und Django als Server verwendet werden. Der Client-Benutzer legt den Bereich und die Ebenen fest und sendet dann die Druckanforderung (die sich auf die Parameter bezieht, dh Kartenbereich, Namen der Ebenen) an den Server. Der Server übernimmt diese Anforderung und ruft WMS / WFS erneut unter Verwendung der Anforderungsparameter auf. Speichern Die Antwort als PDF, exportieren Sie diesen PDF-Link zum Client.

Der schwierige Teil ist, wie der Server WMS / WFS aufruft und diese Antworten kombiniert / überlagert (dh diese Karten / Layer zusammenfügt, da WMS normalerweise die Basiskarte ist und WFS auf die Feature-Layer verweist), um dieses kombinierte Objekt endgültig zu speichern als Bild.

In aktuellen Antworten scheint urllib eine gute zu sein, aber ich bin nicht sicher, wie ich diese Antworten (WMS, WFSs) miteinander kombinieren soll. OWSLib scheint auch eine andere gute Option zu sein, aber es zeigt an, dass es sich um ein Client-Programmiertool handelt. Ich bin ein wenig verwirrt darüber, ob es für meine Verwendung geeignet ist ...

sonstige weitere eingänge ???

schätzen!

Simon
quelle
Ich glaube nicht, dass es das gibt, aber es ist eine gute Idee!
OptimizePrime
Ich habe gerade bemerkt, dass die aktualisierte Frage mit meiner Frage zum Kombinieren von WMS in PDF zusammenhängt.
MarkJ

Antworten:

18

Es gibt OWSLib, die genau das bereitstellen sollte, was Sie benötigen.

OWSLib ist ein Python-Paket für die Client-Programmierung mit den Schnittstellenstandards des Open Geospatial Consortium (OGC) und den zugehörigen Inhaltsmodellen.

OWSLib bietet eine gemeinsame API für den Zugriff auf Service-Metadaten und Wrapper für zahlreiche OGC-Web-Service-Schnittstellen.

Dokumentation und Beispiele hier . Client bedeutet in diesem Zusammenhang, dass es sich um eine Client-Anwendung für einen WMS / WFS-Server handelt. Sie kann bei Bedarf auf einem Server ausgeführt werden.

Nachdem Sie Ihrer Antwort weitere Details hinzugefügt haben, sieht es so aus, als würde die MapFish-Druckanwendung genau Ihren Anforderungen entsprechen. Es ist eine Java-Anwendung, die in OpenLayers integriert werden kann und Kacheln, WMS, WFS usw. zusammenfügt und ein PDF erzeugt.

Da es sich um eine Befehlszeilenanwendung handelt, kann sie mit einem Python-Wrapper bearbeitet werden. Weitere Informationen finden Sie unter den folgenden Links:

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

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

geographika
quelle
1
Danke für den Hinweis auf OWSLib, ich hatte noch nie davon gehört.
user2856 18.11.11
7

Sie können die Python-Urllib-Bibliothek verwenden, um ein WMS direkt aufzurufen und die Antwort in eine Datei zu schreiben. Es gibt ein anständiges Beispiel für die Verwendung von urllib in dieser Antwort . Ersetzen Sie einfach die URL durch eine für ein WMS, z. B. 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 .

Sie können auch die GDAL-Bibliothek für den Zugriff auf WMS ( http://www.gdal.org/frmt_wms.html ) und die OGR-Bibliothek für den Zugriff auf WFS ( http://www.gdal.org/ogr/drv_wfs.html ) verwenden.

Wenn Sie ein Bild des WFS erstellen möchten, können Sie mit der Funktion gdal.RasterizeLayer ein JPG erstellen. Es ist ein Beispiel hier .

user2856
quelle
2

Hier ist ein einfaches Beispiel. Auf der Serverseite:

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)}

Und auf Client-Seite mit 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
quelle
0

Mit GeoTools können Sie die Daten von WMS / WFS-Servern abrufen und in ein Java-Grafikobjekt rendern. Dann kann so etwas wie iText in ein PDF konvertieren.

Wenn Sie wirklich Python verwenden müssen, können Sie wahrscheinlich einen Wrapper verwenden, um alles zu verwalten.

Ian Turton
quelle
1
Vielen Dank. aber ich möchte nur Python verwenden ...
Simon