Operationele lagen die evolueren en tijdsgebonden zijn<\/LI><\/UL><\/LI><\/OL>Mijn doel is te laten zien hoe data in elk van bovenstaande velociteitsscenario's kan worden aangeboden, op een cloud native manier, en in ArcGIS kan worden gebracht. De gemeenschappelijke draad is dat het cloud native formaat dat we zullen gebruiken GeoParquet is in een publieke S3-API compatibele objectopslag zoals AWS. In alle gevallen gebruiken we ArcPy en DuckDB in notebooks of scripttools voor dataconsumptie, met het begrip dat een data beheerder consumenten de benodigde tools zou leveren om ArcGIS de data te laten consumeren. De combinatie van S3, GeoParquet en DuckDB biedt een performante en functionele implementatie in ArcGIS.<\/STRONG><\/P>Laten we erin duiken.<\/P> <\/P> <\/P>Periodieke Bulkvervanging<\/H3> <\/P>Mijn onderwerpdata is Overture Maps Foundation Division Area-features, een dataset op wereldschaal die maandelijks wordt uitgebracht. Het datamodel omvat polygoongeometrie met een primaire plaatsnaam en een struct-object met alternatieve namen in vele talen. De brondata zijn op het moment van schrijven tien GeoParquet-bestanden in AWS S3, met een gemeenschappelijk schema. Er is geen logische partitionering. Het informatieproduct dat ik wil is een geodatabase feature class, gerelateerde alternatieve naam tabel plus een geocoding locator die alle namen begrijpt. <\/STRONG>Hier is hoe de featuredata eruitziet over Europa:<\/P>
Division Areas<\/span><\/P>Om mijn informatieproduct te gebruiken, bijvoorbeeld als ik Madrid in Spanje wil vinden met de Bihari-taal (de pop-up toont beschikbare namen voor Madrid) geef ik 2e 48 21 4d 30 3f 21 als adres:<\/P>
92e94892194d93093f921 vindt Madrid<\/span><\/P>Een notebook is geschikt voor het informatieproduct, je kunt het vinden in de blogdownload, en eigenlijk is de enige truc het gebruik van het juiste glob-pad naar de GeoParquet-data, zie deze cel:<\/P>sql = f"""create or replace temp view division_area_view as select
id,
names.primary as primary_name,
class,
subtype,
region,
country,
version,
is_land,
is_territorial,
bbox.xmin as xmin,
bbox.ymin as ymin,
bbox.xmax as xmax,
bbox.ymax as ymax,
division_id,
geometry
from read_parquet('s3://overturemaps-us-west-2/release/{release}/theme=divisions/type=division_area/*.parquet',filename=false, hive_partitioning=1)
where {whereExp}
order by country, ST_Area(geometry) desc;"""
view = conn.sql(sql)<\/code><\/pre>DuckDB kan glob-paden gebruiken voor lokale of externe data, en maakt externe queries met de S3 API, en deze queries worden parallel uitgevoerd over alle bestanden in het glob-pad. Merk op dat het pad een release-identificatie bevat, dit wordt tijdens runtime uit een STAC-catalogus gehaald. Dit is het centrale thema van dit bericht - wanneer en hoe GeoParquet en DuckDB te gebruiken met data die periodiek verandert.<\/STRONG> In dit geval weten we niet welke records zijn veranderd dus kunnen we er niet gemakkelijk op queryen, dus doen we een bulk extractie.<\/STRONG><\/P>Wat als we wel weten welke records zijn veranderd? <\/P> <\/P>Frequent Toevoegen en Upsert<\/H3> <\/P>Mijn voorbeeld van "drukke" data is 311 case data voor San Francisco. De dataset wordt continu bijgewerkt met duizenden gevallen per dag die worden geopend, bewerkt of gesloten, maar niet opgeschoond, en gaat terug tot 2008. Op het moment van schrijven is de bulkdownload 8 miljoen features, hier gezien op schaal 1:10000:<\/P>
311 Cases in San Francisco<\/span><\/P>Er bestaan veel "event" datasets zoals deze, dus hoe kan de dataset efficiënt worden geleverd op een cloud native manier? Het antwoord berust op het feit dat de data timestamp-velden heeft voor wanneer cases worden geopend, bijgewerkt en gesloten, waarbij het veld updated_datetime wordt vernieuwd bij elke statuswijziging. Omdat de open data site van San Francisco (en daarmee het systeem van registratie erachter) een API heeft die queryen ondersteunt kan dit gedaan worden voor wijzigingen gebaseerd op updated_datetime. Hier is de aanpak die wordt gebruikt in de tools gedeeld in de blogdownload:<\/P>Doe een initiële bulkdownload naar een baseline GeoParquet-bestand<\/LI>Op frequente basisQuery het bestaande GeoParquet-bestand(en) voor de maximale updated_datetime waarde<\/LI>Query het 311 registratiesysteem voor records recenter dan de maximale waardeDit is een snelle query<\/LI><\/UL><\/LI>Schrijf het queryresultaat naar een nieuw aanvullend GeoParquet-bestandAlle GeoParquet-bestanden moeten zich op hetzelfde glob-pad bevinden<\/LI><\/UL><\/LI><\/UL><\/LI>Naar behoefte query de set GeoParquet-bestanden om relevante data te extraherenDergelijke query maakt gebruik van een Eenvoudige maar krachtige SQL-clausule, lees verder...<\/LI><\/UL><\/LI><\/UL>Hier is een voorbeeldquery waarbij ik alle 311 cases tot nu toe voor 2026 binnen een polygoon extraheer naar een geheugen feature class - daar deed hij 4 seconden over. Er zijn ongeveer 8500 features.<\/P>
San Francisco Query<\/span><\/P>De querytool is een scripttool, zijn geheime ingrediënt is de QUALIFY-clausule. De GeoParquet-bestanden gemaakt van dagelijkse case-data zullen duplicaten bevatten vanwege de levenscyclus van cases (opengesteld op ene dag, bewerkt op andere dag, gesloten op latere dag) dan willen wij slechts de meest recente rij per service_request_id waarde over alle GeoParquet-bestanden - de QUALIFY-clausule doet dit voor ons bij het queryen van parquet-data.<\/P> conn.sql(f"""create or replace temp view sf311_view as select
service_request_id,requested_datetime,closed_date,updated_datetime,
status_description,status_notes,agency_responsible,service_name,
service_subtype,service_details,address,street,supervisor_district,
neighborhoods_sffind_boundaries,police_district,source,media_url,
bos_2012,data_as_of,data_loaded_at,ST_AsWKB(GEOM) as wkb
from read_parquet('{pqPath}',filename=false)
where {where}
and ST_Intersects(ST_GeomFromText('{wkt}'), GEOM)
qualify row_number() over (partition by service_request_id order by updated_datetime desc) = 1;""")<\/code><\/pre> <\/P>Dus nu hebben we een eenvoudige manier om snel veranderende gegevens op een cloud-native manier te leveren met snelle queries.<\/P>Wat als we behoorlijk grote gegevens hebben maar geen manier om te zoeken naar veranderingen? <\/P> <\/P>Voortdurend Invoegen, Bijwerken en Verwijderen van Bewerkingenen<\/H3> <\/P>Gegevens die onderhevig zijn aan intensief vertakt versiebeheer zijn waardevol werk voor GIS, en hoewel je de gegevensstatus kunt delen door toegang te geven tot de onderliggende feature services, zal het toevoegen van een publieke mapping workload aan de server niet worden gewaardeerd door de beheerder. Het blijkt dat je de status van de gegevens kunt delen, met ondersteuning voor tijdreizen, met een cloud-native benadering<\/STRONG>. Wat dit mogelijk maakt is het insert-only datamodel<\/STRONG> van vertakt versiebeheer<\/STRONG> - de status van een feature op elk moment wordt bepaald door GDB_FROM_DATE in combinatie met OBJECTID - de rij met de nieuwste GDB_FROM_DATE voor elke unieke waarde van OBJECTID is de huidige status van een feature, en als je zoekt naar eerdere GDB_FROM_DATE waarden krijg je tijdreizen. Het enige trucje is het maken van GeoParquet-bestanden die bewerkingsmomenten vertegenwoordigen, maar dan komt de QUALIFY-clausule weer te hulp om de gegevens te leveren die je wilt.<\/P>Hier zijn twee weergaven van perceelsgegevens over hetzelfde gebied en gebruikmakend van dezelfde bron GeoParquet-bestanden<\/STRONG>.<\/P>
Huidige en eerdere momenten<\/span><\/span><\/P>De linkerweergave is het laatste moment, de rechterweergave is op een eerder moment, je kunt zien dat er veel perceelverdeling heeft plaatsgevonden. De gegevensbron behoudt de volledige gegevensgeschiedenis, bewerkingen resulteren in nieuwe GeoParquet-bestanden die worden toegevoegd aan een map of cloud object store. Hier heb ik een basislijn 1.46GB GeoParquet-bestand voor de oorspronkelijke staat van de gegevens met een paar kleine GeoParquet-bestanden met bewerkingen over twee weken.<\/STRONG><\/P>
GeoParquet-bestanden met volledige gegevensgeschiedenis<\/span><\/span><\/P>Hier is een manifest van het blog downloadbestand CloudNativeDataDistribution.zip<\/STRONG>:<\/P>ImportCurrentDivisionAreas.ipynb<\/STRONG> notebookDownloadt Overture Division Area features naar je project home geodatabase<\/LI>Maakt meertalige namen voor features in een gerelateerde tabel<\/LI>Maakt of vernieuwt een locator met Division Area features als referentiegegevens<\/LI><\/UL><\/LI>GetBaselineSF311<\/STRONG> spatial ETL toolExtraheert de volledige 311 dataset voor San Francisco naar GeoParquet<\/LI>Vereist ArcGIS Data Interoperability<\/LI>Vereist een account en app token<\/LI><\/UL><\/LI>GetUpdatesSF311<\/STRONG> spatial ETL toolExtraheert 311 case data recenter dan enige in een bestaand GeoParquet-bestand<\/LI>Maakt een nieuw GeoParquet-bestand aan<\/LI>Vereist ArcGIS Data Interoperability<\/LI>Vereist een account en app token<\/LI><\/UL><\/LI>Generate311Points <\/STRONG>script toolDemonstreert het gebruik van de GeoParquet-bestanden om een geheugen feature class te maken<\/LI><\/UL><\/LI>ExtractCurrentParcels.ipynb<\/STRONG> notebook
Demonstreert het extraheren van de nieuwste gegevensstatus van GeoParquet-bestanden in een vertakt versiebeheerd datamodel<\/LI><\/UL><\/LI>ExtractEarlierParcels.ipynb<\/STRONG> notebookDemonstreert het extraheren van een eerdere gegevensstatus van GeoParquet-bestanden in een vertakt versiebeheerd datamodel<\/LI><\/UL><\/LI><\/UL>Niet inbegrepen, maar op verzoek beschikbaar, zijn de tools die gebruikt zijn om GeoParquet-bestanden voor de perceelsgegevens te bouwen. Onthoud dat waar mijn voorbeeldtools lokale bestandsopslag gebruiken voor GeoParquet, je in productie een cloud object store zou gebruiken, zoals AWS S3.<\/P>Nu, hoewel ik hoop je te zien op de User Conference 2026 in San Diego, als je meer aanmoediging nodig hebt hier is alvast een sneak preview van een demo die Overture Building theme data in een scene brengt. Kijk of je een paar easter egg script tools kunt vinden in de blog download 😉<\/span>.<\/P>
Overture Buildings<\/span><\/span><\/P> <\/P>