Background
Suppose you want to filter for observations in your city or town. You’ve already searched for an existing place in iNaturalist for your city, but you can’t find one. So you look at the Place tab in iNaturalist’s Getting Started Guide, and using those instructions, you begin to create a place…
You quickly realize the boundaries are too complex to draw by hand, and you see that you can also create boundaries for your place using a KML file. But how do you get your hands on a KML file?
Sometimes if you go to your city’s website or open data portal, they will provide GIS data, including city administrative boundaries. For example, my city has a GIS open data portal which provides city boundaries, park boundaries, etc. Usually, you’ll just have to convert the data, often delivered in another format like Shapefile or GeoJSON, to KML. (You can search the forum or the web for conversion instructions. The rest of this tutorial also talks about one way to take Shapefile data and export a KML.)
But if your city doesn’t provide such data, then read on…
Get geography data from the Census Bureau
Besides providing lots of demographic and economic data, the US Census Bureau has tons of geographic data. Most relevant to this tutorial, just about any US city or town should have boundaries defined in the Census Bureau’s TIGER/Line Places Shapefile dataset or County Subdivision Shapefile dataset.
In Alabama, Arizona, California, Colorado, Delaware, Florida, Georgia, Hawaii, Idaho, Kentucky, Montana, Nevada, New Mexico, Oklahoma, Oregon, South Carolina, Texas, Utah, Washington, and Wyoming, relevant boundaries should be found in the Places set, while in other states, relevant boundaries may be found in either set.
In this tutorial, we’ll use Marfa, TX, as the town for which we’ll create our KML file.
We’ll start by going to the Tiger/Line Places download page. Then we’ll select our state (in this case, Texas), and then click the download button:
When .zip file has been fully downloaded, extract or copy its contents into a new folder. You can choose whatever location you like, but for this example, I’ve extracted to C:\Texas Places on my machine:
If you’re working with one of the states not listed above, you might have to repeat this process to get the appropriate data from the County Subdivision Shapefile dataset.
Select the boundaries for your city
To handle the rest of the process, let’s use QGIS, a popular free and open-source GIS application. Download and install it, if you don’t already have it.
Add a basemap layer
Open QGIS, and we’ll start a new project with an OpenSteetMap basemap. Look in the left Browser pane, expand the XYZ Tiles node, and look for a predefined OpenStreetMap connection. If the OSM connection doesn’t already, exist, right-click on the XYZ node, and select New Connection, and define it like so when prompted (and save when done):
Name: | OpenStreetMap |
URL: | https://tile.openstreetmap.org/{z}/{x}/{y}.png |
Min Zoom Level: | 0 |
Max Zoom Level: | 19 |
Double-click the OSM connection to add an OSM layer to your project.
Add the Census geography layer
Now at the top of the QGIS screen, go to Layer > Add Layer > Add Vector Layer… (or press Ctrl+Shift+V). When prompted, find and select the file with the .shp extension in the new folder that you created earlier. Then click Add.
At this point, you may get a screen like this (you may have to resize it a bit to see all the columns in the tranformation table):
The Census data are defined in a coordinate system that is different from what we use for web mapping, and there are multiple pre-defined transformations that QGIS provides in this case. So we just need to pick the transformation we prefer. If in doubt, just select the first one. Otherwise, you can select one more appropriate for your Area of Use. (For Marfa, I can use the transformation appropriate for Texas west of 100 deg W.)
Then click Ok, and then close the Data Source Manager window.
Find and select your city
At this point, you should have an OSM basemap with some Census polygons on top. The Census polygons are completely opaque by default. So to help us see the OSM map below the polygons, we’ll go to the Layer pane on the left side of the screen, right click the Census layer, and select Styles > Edit Symbol…, like so:
In the pop-up, dial down the opacity of the layer to, say, 50%. You can also change the colors of the polygons, if you like, though colors won’t really matter in the final product. Then click Ok.
Now zoom in and pan as needed to find the city polygon that you’re interested in (below, Marfa is on the left, with Alpine on the right just for reference):
When your city polygon is in view on the map, use the Feature Selection Tool () in the toolbar to select the polygon. The polygon should appear yellow when selected (below, Marfa is yellow, Alpine is still pink):
If for some reason you’re having a hard time finding your city on the map, you can query by name. Click the Open Attribute Table button in the toolbar (), or press F6. When the pop-up appears, you can select the city in the alphabetical list of names in the left pane. Alternatively, click on the filter button (), query by name, then click Select Features at the bottom:
Just to make sure you’ve selected the right thing, you can click the filter button again, and then click Zoom to Features. Then close the Attribute Table Pop-up to return to the main QGIS window.
(If you didn’t find your place of interest in the your state’s Places shapefile, you might have to repeat this process of adding a layer and search for your place of interest using the County Subdivision shapefile.)
Export a KML file
With your place of interest selected, now go to the Layers pane, right-click the Census layer that contains the selected item, and select Export > Save Selected Features As…
When prompted, choose KML as your export file format, and browse for a destination folder and define a file name for the file that you want to create. (In this example, I’ll save my file as C:\Texas Places\Marfa.kml.) By default, the layer name will be the same as the file name you select, but you can change it, if you like. Leave all the other options as is, and click OK:
A new layer with only the boundary for your city should have been added to the map. Go to the Layers pane, and uncheck the Census layer that contains all places for the state to hide it from view. if successful, you should see just a polygon for just your city (brown in my example below) on top of the OSM basemap:
Look for your new KML file in your chosen destination folder. Once you’ve confirmed that it exists, you can close QGIS. (You don’t need to save anything if you don’t want to.) You can then proceed to load the KML into iNaturalist.
Just for reference, if you open up your KML file in a code or plain text editor (like Notepad, if you use Windows), you can see the contents of your created file. For example, this is what the contents of the Marfa KML look like:
<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="Marfa" id="Marfa">
<SimpleField name="STATEFP" type="string"></SimpleField>
<SimpleField name="PLACEFP" type="string"></SimpleField>
<SimpleField name="PLACENS" type="string"></SimpleField>
<SimpleField name="GEOID" type="string"></SimpleField>
<SimpleField name="NAMELSAD" type="string"></SimpleField>
<SimpleField name="LSAD" type="string"></SimpleField>
<SimpleField name="CLASSFP" type="string"></SimpleField>
<SimpleField name="PCICBSA" type="string"></SimpleField>
<SimpleField name="PCINECTA" type="string"></SimpleField>
<SimpleField name="MTFCC" type="string"></SimpleField>
<SimpleField name="FUNCSTAT" type="string"></SimpleField>
<SimpleField name="ALAND" type="float"></SimpleField>
<SimpleField name="AWATER" type="float"></SimpleField>
<SimpleField name="INTPTLAT" type="string"></SimpleField>
<SimpleField name="INTPTLON" type="string"></SimpleField>
</Schema>
<Folder><name>Marfa</name>
<Placemark>
<name>Marfa</name>
<Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
<ExtendedData><SchemaData schemaUrl="#Marfa">
<SimpleData name="STATEFP">48</SimpleData>
<SimpleData name="PLACEFP">46620</SimpleData>
<SimpleData name="PLACENS">02411031</SimpleData>
<SimpleData name="GEOID">4846620</SimpleData>
<SimpleData name="NAMELSAD">Marfa city</SimpleData>
<SimpleData name="LSAD">25</SimpleData>
<SimpleData name="CLASSFP">C1</SimpleData>
<SimpleData name="PCICBSA">N</SimpleData>
<SimpleData name="PCINECTA">N</SimpleData>
<SimpleData name="MTFCC">G4110</SimpleData>
<SimpleData name="FUNCSTAT">A</SimpleData>
<SimpleData name="ALAND">4202784</SimpleData>
<SimpleData name="AWATER">0</SimpleData>
<SimpleData name="INTPTLAT">+30.3106795</SimpleData>
<SimpleData name="INTPTLON">-104.0254518</SimpleData>
</SchemaData></ExtendedData>
<MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>-104.038565,30.309834 -104.035539,30.309219 -104.035542,30.309316 -104.035545,30.30941 -104.035547,30.30984 -104.035555,30.31113 -104.035558,30.311561 -104.035578,30.314532 -104.035608,30.318811 -104.034812,30.318827 -104.030973,30.318825 -104.028002,30.318824 -104.027505,30.318833 -104.026015,30.318861 -104.025519,30.318871 -104.025241,30.318876 -104.024918,30.318883 -104.023871,30.318906 -104.023118,30.318909 -104.022518,30.318913 -104.022491,30.318913 -104.022411,30.318913 -104.022385,30.318914 -104.022434,30.319056 -104.02257,30.319443 -104.022583,30.319484 -104.022629,30.319628 -104.022683,30.319801 -104.02278,30.320109 -104.022847,30.32032 -104.022902,30.320493 -104.022963,30.320685 -104.023117,30.321205 -104.023137,30.3213 -104.023181,30.321506 -104.023219,30.321687 -104.023312,30.322122 -104.023328,30.322233 -104.023356,30.322417 -104.023071,30.32242 -104.022217,30.32243 -104.021933,30.322434 -104.021649,30.322435 -104.020797,30.322438 -104.020666,30.322439 -104.020305,30.322444 -104.019855,30.322448 -104.019827,30.322448 -104.019743,30.322448 -104.019715,30.322448 -104.019489,30.322448 -104.018813,30.322448 -104.018588,30.322448 -104.018394,30.322447 -104.017814,30.322444 -104.017596,30.322444 -104.017415,30.322443 -104.016798,30.32244 -104.016593,30.32244 -104.016594,30.322249 -104.016599,30.321677 -104.016602,30.321487 -104.016602,30.321286 -104.016604,30.320685 -104.016624,30.320664 -104.016606,30.320346 -104.016609,30.319928 -104.01661,30.31979 -104.016608,30.31957 -104.016604,30.318997 -104.01652,30.318993 -104.016302,30.318984 -104.01608,30.318983 -104.015417,30.318981 -104.015196,30.318981 -104.014986,30.31898 -104.014356,30.31898 -104.014242,30.31898 -104.014242,30.318885 -104.014243,30.318691 -104.014246,30.318109 -104.014248,30.317916 -104.014247,30.317728 -104.014243,30.317164 -104.014243,30.316976 -104.014242,30.316799 -104.014239,30.31627 -104.014239,30.316094 -104.014239,30.315875 -104.014241,30.315221 -104.014242,30.315004 -104.014242,30.314745 -104.014243,30.31397 -104.014244,30.313712 -104.014243,30.313562 -104.014242,30.313113 -104.014242,30.312964 -104.014239,30.3129 -104.014233,30.312708 -104.014231,30.312645 -104.01423,30.312349 -104.01423,30.311463 -104.01423,30.311168 -104.014231,30.309634 -104.014236,30.305034 -104.014238,30.30414 -104.014877,30.304133 -104.01506,30.304139 -104.015345,30.30416 -104.015544,30.304161 -104.017551,30.304176 -104.01822,30.304182 -104.018498,30.304184 -104.019334,30.30419 -104.019613,30.304192 -104.019652,30.304191 -104.01977,30.304191 -104.01981,30.304191 -104.019994,30.30419 -104.02028,30.304188 -104.020545,30.304187 -104.02073,30.304187 -104.020881,30.304186 -104.021337,30.304183 -104.021422,30.304183 -104.021705,30.304186 -104.022355,30.304196 -104.022572,30.3042 -104.022792,30.304202 -104.023452,30.304209 -104.023672,30.304212 -104.024003,30.304203 -104.024145,30.304203 -104.024405,30.3038 -104.024471,30.30369 -104.02467,30.303364 -104.024737,30.303255 -104.024703,30.303104 -104.024601,30.302654 -104.024567,30.302504 -104.024512,30.301923 -104.024467,30.301437 -104.02451,30.301158 -104.024692,30.30064 -104.024938,30.300289 -104.025274,30.299813 -104.025385,30.29972 -104.02559,30.299551 -104.025683,30.299407 -104.025763,30.299286 -104.025908,30.299129 -104.026345,30.298658 -104.026491,30.298502 -104.026646,30.298302 -104.027115,30.297705 -104.027271,30.297506 -104.027341,30.297382 -104.027553,30.297013 -104.027624,30.29689 -104.027732,30.296928 -104.028056,30.297042 -104.028164,30.29708 -104.028987,30.297411 -104.02926,30.29752 -104.029296,30.297535 -104.032803,30.297528 -104.033986,30.297526 -104.033467,30.298275 -104.033129,30.298532 -104.033218,30.298613 -104.033164,30.298683 -104.032941,30.299062 -104.032767,30.299282 -104.03098,30.301878 -104.029805,30.303538 -104.029558,30.303888 -104.029496,30.303997 -104.029471,30.304053 -104.02934,30.304269 -104.031225,30.304308 -104.031346,30.304291 -104.0315,30.304297 -104.032318,30.304283 -104.032592,30.304279 -104.03289,30.304282 -104.033784,30.304294 -104.034083,30.304298 -104.034378,30.304302 -104.035263,30.304315 -104.035559,30.30432 -104.035825,30.30432 -104.036269,30.304321 -104.036626,30.304315 -104.036719,30.304314 -104.036893,30.304329 -104.037212,30.304329 -104.038171,30.304331 -104.038491,30.304332 -104.03849,30.304514 -104.038488,30.30506 -104.038488,30.305243 -104.038487,30.305297 -104.038487,30.305458 -104.038487,30.305513 -104.038497,30.305647 -104.038502,30.305699 -104.038502,30.306052 -104.038503,30.306188 -104.038502,30.306232 -104.038502,30.306366 -104.038502,30.306411 -104.038501,30.306549 -104.0385,30.306964 -104.0385,30.307103 -104.038499,30.307284 -104.038497,30.30783 -104.038497,30.308012 -104.038498,30.308223 -104.038501,30.308857 -104.038502,30.308978 -104.038503,30.309069 -104.038504,30.309243 -104.038488,30.309542 -104.038484,30.309631 -104.038488,30.309689 -104.038498,30.309749 -104.038527,30.3098 -104.038565,30.309834</coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry>
</Placemark>
</Folder>
</Document></kml>
Other Notes
There are other ways to get geographic boundaries (ex. https://forum.inaturalist.org/t/how-to-import-a-place-from-openstreetmap-into-inaturalist-using-overpassturbo-web-based/41046), but I’ve decided to document this workflow because it think it covers some concepts / skills that I think are are broadly applicable. If you have questions or thoughts, feel free to comment in the discussion, and I’ll also turn this original post into a Wiki in case anyone wants to add / change information.