<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>spilth.org</title><description>Something Spilled</description><link>https://spilth.org/</link><item><title>NYU Geospatial Work</title><link>https://spilth.org/blog/2026-05-28-nyu-geospatial-work/</link><guid isPermaLink="true">https://spilth.org/blog/2026-05-28-nyu-geospatial-work/</guid><description>An overview of the work I did over the last couple of years with NYU&apos;s Digital Libraries team.</description><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I just wrapped up a 2-year stint with New York University’s Digital Library department, mostly helping them with their geospatial data but also working on some ancillary projects as well.&lt;/p&gt;
&lt;h2&gt;GeoBlacklight&lt;/h2&gt;
&lt;p&gt;I was initially brought on to help with their &lt;a href=&quot;https://geoblacklight.org/latest/&quot;&gt;GeoBlacklight&lt;/a&gt; instance, the &lt;a href=&quot;https://geo.nyu.edu&quot;&gt;NYU Spatial Data Repository&lt;/a&gt;. GBL is a &lt;a href=&quot;https://rubyonrails.org&quot;&gt;Ruby on Rails&lt;/a&gt; project that sits in front of &lt;a href=&quot;https://solr.apache.org&quot;&gt;Solr&lt;/a&gt; to make finding Geospatial data fast and discoverable via a map interface. The combination of Ruby/Rails and geospatial data was right up my alley.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I upgraded their instance of GBL to version 4, made functional improvements, fixed bugs, addressed CVEs, integrated &lt;a href=&quot;https://newrelic.com&quot;&gt;New Relic&lt;/a&gt;, updated the &lt;a href=&quot;https://www.capify.org/index.html&quot;&gt;Capistrano&lt;/a&gt; deployment, did some exploratory work with &lt;a href=&quot;https://anubis.techaro.lol/&quot;&gt;Anubis&lt;/a&gt; and did some additional work to deter bots and crawlers. I also worked on an &lt;a href=&quot;https://docs.ansible.com/&quot;&gt;Ansible&lt;/a&gt; playbook to automate setting up GeoServer on &lt;a href=&quot;https://rockylinux.org&quot;&gt;Rocky Linux&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;OpenGeoMetadata, GeoServer &amp;amp; PostGIS&lt;/h3&gt;
&lt;p&gt;The source of their data for the Spatial Data Repository is a collection of JSON files using the &lt;a href=&quot;https://opengeometadata.org/ogm-aardvark/&quot;&gt;OGM Aardvark Schema&lt;/a&gt;, found in the &lt;a href=&quot;https://github.com/OpenGeoMetadata/edu.nyu&quot;&gt;edu.nyu OGM Repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To help manage this data I created a command-line tool called &lt;a href=&quot;https://github.com/NYU-DataServices/sdr-data-loader&quot;&gt;sdr-data-loader&lt;/a&gt; using Python to automate loading Shapefiles into &lt;a href=&quot;https://postgis.net&quot;&gt;PostGIS&lt;/a&gt; and publishing them to &lt;a href=&quot;https://geoserver.org&quot;&gt;GeoServer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I took this opportunity to generate an “audit report” to discover and diagnose any records with issues such as missing database records, unpublished layers or invalid IDs. In the end that report helped me fix about 1600 records with issues.&lt;/p&gt;
&lt;h3&gt;PMTiles &amp;amp; COG&lt;/h3&gt;
&lt;p&gt;I did some exploratory work to determine the feasibility of converting some of their geospatial data to &lt;a href=&quot;https://github.com/protomaps/PMTiles&quot;&gt;PMTiles&lt;/a&gt; or &lt;a href=&quot;https://cogeo.org&quot;&gt;Cloud Optimized GeoTIFFs&lt;/a&gt; to eventually remove the need for GeoServer. Due to the volume and heterogeneous nature of their data, as well as somewhat immature support at the time for those technologies, it was decided not to pursue those formats for now.&lt;/p&gt;
&lt;h2&gt;Invenio RDM&lt;/h2&gt;
&lt;p&gt;The latter half of my time with NYU was spent working on their &lt;a href=&quot;https://inveniordm.docs.cern.ch&quot;&gt;Invenio RDM&lt;/a&gt; instance &lt;a href=&quot;https://ultraviolet.library.nyu.edu&quot;&gt;UltraViolet&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;GeoSpatial Support&lt;/h3&gt;
&lt;p&gt;My main goal was to add geospatial functionality to Invenio RDM - the ability to add records with geospatial data that could be previewed using Geoserver both while editing and viewing records. I created a React component that talks to a Python backend to validate record data against GeoServer. This lets depositors get immediate feedback on whether the data they have entered is correct.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I created a data loading CLI (also in Python) to help automate ingesting their geospatial data into Ultraviolet. This included converting data from OGM’s Aardvark format to a format compatible with Invenio RDM&lt;/p&gt;
&lt;h3&gt;Upgrades and Entra ID Support&lt;/h3&gt;
&lt;p&gt;During the course of working with Invenio RDM I updated their instance from version 12 to 13 and added OAuth support for Microsoft Entra ID.&lt;/p&gt;
&lt;h3&gt;GeoJSON Previewer&lt;/h3&gt;
&lt;p&gt;As an extracurricular project I created a file previewer for GeoJSON after working with Invenio RDM’s previewers for so long. That should be available in the next release of the project.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Fun Work&lt;/h2&gt;
&lt;p&gt;I had a great time working with the folks in NYU’s Digital Libraries department and hope to engage with them again soon. It was also nice to be able to contribute to open source projects like Invenio RDM and GeoBlacklight.&lt;/p&gt;
&lt;p&gt;I’m excited to takes some of the GeoSpatial learnings from this engagement and bring them over to &lt;a href=&quot;https://lostmapper.com&quot;&gt;the Lost Mapper&lt;/a&gt;, particularly how to set up an instance of GeoBlacklight and ingest your organizations data.&lt;/p&gt;
&lt;p&gt;My &lt;a href=&quot;https://github.com/spilth/gis-dockerized&quot;&gt;gis-dockerized project&lt;/a&gt; came in handy many times while testing out scripts and working with data. A miniature version of it even made its way into the sdr-data-loader!&lt;/p&gt;</content:encoded></item><item><title>Stunt List for The Expanse RPG</title><link>https://spilth.org/blog/2026-05-26-expanse-rpg-stunts/</link><guid isPermaLink="true">https://spilth.org/blog/2026-05-26-expanse-rpg-stunts/</guid><description>The origins of a mobile-friendly tool for Expanse RPG players.</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This past weekend I ran my first ever session of &lt;a href=&quot;https://greenroninstore.com/collections/the-expanse-rpg&quot;&gt;The Expanse RPG&lt;/a&gt;. I’m running the adventure Cupbearer from the Quickstart but also picked up the Game Master’s Kit which includes hand outs with all the Stunts in the game - there’s like 130 of them.&lt;/p&gt;
&lt;p&gt;My players found the lists to be a bit overwhelming and hard to share. I mentioned, “Wouldn’t it be neat if you each had the Stunts on your phone and could filter them by Category and how many Stunt Points you had to spend?”, so I went ahead and made that over the course of the day yesterday: &lt;a href=&quot;/expanse-stunts/&quot;&gt;The Expanse RPG Stunt List&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After sharing it with various Expanse RPG communities I’ve come to realize that the Stunts list in the GM’s Kit and the ones in the core rulebook are a little different, so I’ll be fixing those over the next few days. But there seems to be only a few of those and their mostly off by 1 point, so it’s still totally usable!&lt;/p&gt;</content:encoded></item><item><title>arc2ogm - Initial Thoughts</title><link>https://spilth.org/blog/2025-07-09-arc2ogm/</link><guid isPermaLink="true">https://spilth.org/blog/2025-07-09-arc2ogm/</guid><description>Some thoughts about creating a tool to make ArGIS REST Services more discoverable using GeoBlacklight.</description><pubDate>Wed, 09 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The Struggle&lt;/h2&gt;
&lt;p&gt;One of the things I’ve struggled with as a hobbyist mapper is finding and keeping track of GIS data sources on the internet. And because ESRI is such a giant, a large number of state GIS departments end up using ArcGIS. And while there are a large number of ArcGIS REST Services out there, they are not well advertised, and the interface for browsing them isn’t very… mappy.&lt;/p&gt;
&lt;h2&gt;The Inspiration&lt;/h2&gt;
&lt;p&gt;I recently did some work for NYU on their &lt;a href=&quot;https://geo.nyu.edu&quot;&gt;Spatial Data Repository&lt;/a&gt; which is built on &lt;a href=&quot;https://geoblacklight.org&quot;&gt;GeoBlacklight&lt;/a&gt;. GeoBlacklight is backed by Solr and ingests documents using the &lt;a href=&quot;https://opengeometadata.org/ogm-aardvark/&quot;&gt;OpenGeoMetadata Aardvark Schema&lt;/a&gt;. The documents describe mapping resources of various kinds.&lt;/p&gt;
&lt;p&gt;A minimal Aardvark file looks something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;id&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;foo-trails&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;dct_title_s&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;Trails&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;gbl_resourceClass_sm&quot;&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;Web services&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ],&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;dct_accessRights_s&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;Public&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;gbl_mdModified_dt&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;2025-07-09T00:57:51Z&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;gbl_mdVersion_s&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;Aardvark&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;schema_provider_s&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;Testing&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;dct_references_s&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;{&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;urn:x-esri:serviceType:ArcGIS#FeatureLayer&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;https://services6.arcgis.com/9QlSLDqa0P1cHLhu/ArcGIS/rest/services/WRD_WMA_Public/FeatureServer/13&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;}&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;locn_geometry&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;ENVELOPE(-85.41306473369147, -81.12480564035837, 34.975019430744, 30.786567131737005)&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;gbl_resourceType_sm&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;Line data&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ingesting that file results in a GeoBlacklight search results that look like this:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And a record page that looks like this:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;It’s a nice visual way to browse and filter map data in order to find what you’re looking for. Imagine if there was a GeoBlacklight server that cataloged all the public ArcGIS REST Servers out there?&lt;/p&gt;
&lt;h2&gt;The Idea&lt;/h2&gt;
&lt;p&gt;My goal is to create a tool (tentatively called &lt;code&gt;arc2ogm&lt;/code&gt;) that you can point at a collection of ArcGIS REST Service URLs, and it will crawl them and turn each compatible resource into an Aardvark document. Then I’d stand up a GeoBlacklight instance and ingest all those documents for others to browse and search.&lt;/p&gt;
&lt;p&gt;It’s likely that the cost of the server is not something I can warrant right now, so at least the tool and the resulting data could be useful to others.&lt;/p&gt;
&lt;h2&gt;The Minimal Viable Project&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://opengeometadata.org/ogm-aardvark/&quot;&gt;Aardvark schema&lt;/a&gt; only has a few required fields, though a few more make the record much more usable in GeoBlacklight:&lt;/p&gt;
&lt;h3&gt;Required Fields&lt;/h3&gt;
&lt;h4&gt;Title&lt;/h4&gt;
&lt;p&gt;This is the name of the resource which should be pretty straightforward. A challenge here is that they can often be named somewhat generically because they are only thought about in the context of a county or state.&lt;/p&gt;
&lt;h4&gt;Resource Class&lt;/h4&gt;
&lt;p&gt;This field will likely be hard-coded because we’re always talking to a “web service.” There might be some subtlety here moving forward though.&lt;/p&gt;
&lt;h4&gt;Access Rights&lt;/h4&gt;
&lt;p&gt;This will likely always be &lt;code&gt;Public&lt;/code&gt; since we’re crawling publicly available resources.&lt;/p&gt;
&lt;h4&gt;ID&lt;/h4&gt;
&lt;p&gt;This is meant to be a unique identifier which I will need some kind of strategy for generating. I suspect this value should be based on the URL (assuming they never change), but this requires further thought.&lt;/p&gt;
&lt;h4&gt;Modified&lt;/h4&gt;
&lt;p&gt;This will just be a timestamp for when the URL was crawled.&lt;/p&gt;
&lt;h4&gt;Metadata Version&lt;/h4&gt;
&lt;p&gt;This will be hardcoded to &lt;code&gt;Aardvark&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Helpful Fields&lt;/h3&gt;
&lt;h4&gt;Creator, Publisher, Provider&lt;/h4&gt;
&lt;p&gt;One of these fields will likely be necessary to identify (and make filterable) the source of the data. It could also identify the title or owner of the ArcGIS REST Server being crawled.&lt;/p&gt;
&lt;h4&gt;Resource Type&lt;/h4&gt;
&lt;p&gt;There’s a canned collection of values for this field, and for the most part, it will just map to whether it contains point, line or polygon data. As I move beyond Feature Services, I assume additional mappings will be necessary.&lt;/p&gt;
&lt;h4&gt;References&lt;/h4&gt;
&lt;p&gt;This field is a collection of URLs related to the data — where you might download or access it from. There are 4 ESRI-specific values for DynamicMapLayer, FeatureLayer, ImageMapLayer and TiledMapLayer.&lt;/p&gt;
&lt;p&gt;The value here makes it possible to display the “Open in ArcGIS Online” link and “Web services” button. You could plug this value into QGIS to load that data on the fly.&lt;/p&gt;
&lt;h4&gt;Geometry&lt;/h4&gt;
&lt;p&gt;This field represents the extent of the data and powers the ability to search by the pannable/zoomable map in GeoBlacklight. This feels like a high priority field to me.&lt;/p&gt;
&lt;p&gt;From my initial development, there will be a challenge here as the Spatial Reference Identifiers (SRIDs) used by some layers aren’t available in &lt;a href=&quot;https://pyproj4.github.io/pyproj/stable/&quot;&gt;pyproj&lt;/a&gt;. From a cursory investigation they &lt;em&gt;do&lt;/em&gt; show up in QGIS, but I suspect it’s less than trivial to bring QGIS’ data sources into a standalone CLI.&lt;/p&gt;</content:encoded></item></channel></rss>