How+to+Import+WFS+Data+into+PostGIS+Using+GeoPandas+-+No+ArcGIS+Needed

How to Import WFS Data into PostGIS Using GeoPandas - No ArcGIS Needed

Ever wanted to directly pull vector data from an ArcGIS WFS (Web Feature Service) and store it into your PostgreSQL/PostGIS database? πŸ’‘

In this quick tutorial, we’ll walk through how to:

  • Fetch live WFS data from an ArcGIS server using GeoPandas

  • Save that spatial data into a PostgreSQL/PostGIS table

  • Do it all with just a few lines of Python 🐍

Whether you’re building a geospatial ETL pipeline or just testing public WFS endpoints, this guide has your back!


🧠 Prerequisites

Before diving in, make sure you have these Python packages installed:

pip install geopandas sqlalchemy psycopg2-binary geoalchemy2

βœ… You’ll also need a running PostgreSQL instance with PostGIS enabled.


πŸ”Œ Step 1 – Define Your WFS URL

We will use a public ArcGIS WFS service for this example. Here’s the sample URL:

wfs_url=
"https://sampleserver6.arcgisonline.com/arcgis/services/SampleWorldCities/MapServer/WFSServer?service=WFS&version=1.0.0&request=GetFeature&typeName=cities"

This URL returns GML-based WFS data of world cities. Most ArcGIS WFS services follow this format — just replace  typeName as needed.


πŸ›  Step 2 – Set Up the PostgreSQL Connection

from sqlalchemy import create_engine

# Replace with your own DB credentials
db_user = "postgres"
db_pass = "*******"  # Change this!
db_host = "localhost"
db_port = "5432"
db_name = "db_data"

engine = create_engine(f"postgresql://{db_user}:{db_pass}@{db_host}:{db_port}/{db_name}")

πŸ’‘ Tip: Make sure your PostGIS extension is enabled with:

CREATE EXTENSION postgis;

🌐 Step 3 – Fetch WFS Data using GeoPandas

import geopandas as gpd

print("⏳ Fetching WFS GML data...")
gdf = gpd.read_file(wfs_url)
print("βœ… Data fetched:", len(gdf), "records")

GeoPandas supports WFS out-of-the-box using fiona in the backend. It can parse GML, GeoJSON, and other OGC-standard formats.


🧱 Step 4 – Store Data into PostGIS

Now let’s write the GeoDataFrame into a spatial table in PostgreSQL:

table_name = "cities_arcgis"

print(f"πŸ’Ύ Saving to table: {table_name}")
gdf.to_postgis(name=table_name, con=engine, if_exists="replace", index=False)
print("πŸŽ‰ Data saved successfully!")

You can also use:

  • if_exists="append" – to add new records

  • if_exists="fail" – to avoid overwriting


πŸ§ͺ Final Output Check

Log in to your PostgreSQL DB and run:

SELECT COUNT(*), ST_AsText(geom) FROM cities_arcgis LIMIT 5;

You should see the WFS cities successfully imported as geometry records. 🎯


πŸš€ Use Cases

This method is perfect for:

  • Automating data ingestion from ArcGIS WFS layers

  • Building PostGIS pipelines from public geoservices

  • Converting live city data, zoning data, land records, and more into local DBs


🧩 Gotchas to Watch For

  • ArcGIS WFS sometimes sends invalid GML geometries — try .buffer(0) if needed

  • Ensure your database supports geometry type and SRID match your WFS data

  • WFS requests can timeout for large datasets — test with smaller filters


πŸ“ Conclusion

With GeoPandas + SQLAlchemy, fetching and storing spatial WFS data becomes smooth and scriptable. This simple pipeline can scale to any WFS service — from cities to zoning boundaries to environmental datasets.


πŸ” Full Script Recap

import geopandas as gpd
from sqlalchemy import create_engine

wfs_url=
"https://sampleserver6.arcgisonline.com/arcgis/services/SampleWorldCities/MapServer/WFSServer?service=WFS&version=1.0.0&request=GetFeature&typeName=cities" db_user = "postgres" db_pass = "**********" db_host = "localhost" db_port = "5432" db_name = "db_data" table_name = "cities_arcgis" engine = create_engine(f"postgresql://{db_user}:{db_pass}@{db_host}:{db_port}/{db_name}") print("⏳ Fetching WFS GML data...") gdf = gpd.read_file(wfs_url) print("βœ… Data fetched:", len(gdf), "records") print(f"πŸ’Ύ Saving to table: {table_name}") gdf.to_postgis(name=table_name, con=engine, if_exists="replace", index=False) print("πŸŽ‰ Data saved successfully!")

❓ Frequently Asked Questions (FAQ)

πŸ”Έ Q1: What is WFS in GIS?

A: WFS (Web Feature Service) is an OGC standard that provides access to vector spatial data (like points, lines, and polygons) over the web. Unlike WMS, which serves images, WFS allows downloading actual geometry + attribute data.


πŸ”Έ Q2: Can GeoPandas read WFS services?

A: Yes! GeoPandas can read WFS services directly  gpd.read_file(wfs_url) as long as the WFS returns valid GML or GeoJSON.


πŸ”Έ Q3: Do I need ArcMap or ArcGIS Pro to fetch WFS data?

A: No. This method uses only Python, so no ESRI software is required. It works even for ArcGIS-hosted WFS services, as long as the service is public or accessible.


πŸ”Έ Q4: What database is used in this tutorial?

A: We use PostgreSQL with the PostGIS extension enabled. This allows us to store and query spatial data like points, lines, and polygons using SQL.


πŸ”Έ Q5: What happens if the WFS has a huge dataset?

A: Large WFS layers may take time or timeout. You can:

  • Use WFS filters (bbox, CQL_FILTER, etc.)

  • Download in chunks

  • Test the response size before importing


πŸ”Έ Q6: Can I append new data to the existing PostGIS table?

A: Yes, simply set it if_exists="append" in the A to_postgis() method to keep old data and add new rows.


πŸ”Έ Q7: Does this method preserve spatial geometry?

A: Absolutely. GeoPandas preserves the geometry column geometryand writes it to PostGIS in the proper spatial format with SRID support.


πŸ”Έ Q8: What are some real-world use cases?

  • Syncing real-time city data into PostGIS

  • Downloading open land parcel boundaries for offline analysis

  • Automating updates for urban planning dashboards

 

Comments

Leave a Reply

Play List