GIS Service configuration

You may have some programs that need to collect an applicant's address to offer services. Those programs may also want to verify that the address exists and matches a standard format, and may also want to verify that the address is in the area that's eligible for the program. For example, a program may only be for applicants living in a certain county. CiviForm uses the external Esri service for both these use cases. CiviForm is not currently compatible with other geolocation services. If you'd like to use another geolocation service, please reach out to the engineering team.

Address Correction

Programs may want to have an applicant's address corrected so that they can verify the address exists and have all addresses in a standard format. This needs to be configured both at the deployment level and at a question level.

If you want to see what results address correction might provide, you can experiment with ArcGIS's world endpoint. Here's a sample query for 700 5th Ave, Seattle WA 98101. For your official deployment, you could choose to use this endpoint instead of defining your own, but you would still need to purchase an Esri subscription and create an Esri API token.

Deployment-level configuration

Before any specific program can use address correction, it must be enabled for your deployment as a whole.

  1. Set ESRI_FIND_ADDRESS_CANDIDATES_URLS to one or more URLs that CiviForm will use to call Esri’s findAddressCandidates service. The service should have a GeocodeServer type. Example URL value: "https://gisdata.seattle.gov/cosgis/rest/services/locators/AddressPoints/GeocodeServer/findAddressCandidates"

[!NOTE] If you are using Esri's ArcGis Online service (arcgis.com), you need to also set a valid api token for ESRI_ARCGIS_API_TOKEN. You can get a token via your arcgis.com account.

  1. Optional, but recommended. Set ESRI_WELLKNOWN_ID_OVERRIDE which forces the service calls to return spatial references using the specified wellknown id value for their coordinate system.

Overriding the default wellKnownId

The Esri API has the ability to return spatial reference data using different coordinate systems via a wellKnownId (a.k.a wkid). Details of that along with links to the long list of possible coordinate systems can be found on the arcgis developer site.

The default wellKnownId is 4326 - GPS which are traditional latitude and longitude value most often thought around of around coordinate systems. Custom hosted installations may set a different value as their default. For example, Seattle defaults to using wellKnownId 2926 - NAD_1983_HARN_StatePlane_Washington_North_FIPS_4601_Feet link.

This works fine as long as calls to correct an address and calls to mapping layers for service area validation are all defaulting to the same wellKnownId. Such as calling both endpoints on the same hosted instance.

Where it becomes a problem is if you want to start mixing calls to different installations.

Example

  1. Call arcgis.com to correct address, returns coordinates using wellKnownId 4326

  2. Call Seattle's hosted instance for map query endpoints for service area validation using values from arcgis.com would result in not being eligible because the coordinates systems don't match

By setting the ESRI_WELLKNOWN_ID_OVERRIDE we force both systems to use the same coordinate system.

Existing data

After we get the corrected address we save the x, y, and wkid as part of the address. Calls to map query endpoints already use the stored wkid to specify what the input spatial reference should be. Existing records will still work as is.

If this override is added after CiviForm users have been using address correction and is different from the previously used default you will end up having new records stored in different format. If that is a concern the solution is to make sure the override value is the same as used before.

This is only an issue if you change the find address endpoint at a later point in time to one with a different default. Such as using Seattle's version to using arcgis.com.

If there is only a single host this will never be a problem since they'll both have the same defaults.

Applying to questions

Once those configuration variables are set up, address correction can be enabled or disabled on any address question using a toggle:

When a user fills out an address question with address correction, CiviForm will use the Esri endpoint to fetch address suggestions. If a suggestion perfectly matches what the user inputted, the suggestion will automatically be used and the user will proceed with the application. Otherwise, the user will be presented with a screen asking them to choose the correct suggested address:

Note that for each block in an application, there can only be one address question with address correction enabled. This is because it's complicated to chain multiple address correction pages together (both from a technical standpoint and from the perspective of an applicant). If multiple address questions need address correction, they can be on different blocks.

Service Area Validation

Service area validation checks whether an address is within a specific area. This can be used for visibility or eligibility conditions. For example, a user may only be eligible for a program if they live in a specific neighborhood.

Service area validation requires that address correction must also be enabled for the question. CiviForm needs the address's latitude and longitude values from Esri to determine if the address is within a certain area, and we only get the latitude and longitude values from Esri's address correction information.

Deployment-level configuration

Step 1: Enable feature flag

Set ESRI_ADDRESS_SERVICE_AREA_VALIDATION_ENABLED to true. Note that ESRI_ADDRESS_CORRECTION_ENABLED must also be set to true.

Step 2: Configure service area map values

Set the four ESRI_ADDRESS_SERVICE_AREA_VALIDATION_* configuration variables to contain the necessary information:

  • ESRI_ADDRESS_SERVICE_AREA_VALIDATION_URLS is the list of URL(s) that CiviForm will use to call Esri’s map query service to determine if the address is within the area specified by the map query service. The map should be a MapService type.

    • Type: String[]

    • Example value: ["https://gisdata.yourcity.gov/server/rest/services/City_Limits/MapServer/1/query"]

  • ESRI_ADDRESS_SERVICE_AREA_VALIDATION_LABELS is the list of labels that CiviForm admins will see when setting up eligibility or visibility conditions.

    • Type: String[]

    • Example values: ["Seattle"], ["Abc County", "Def County", "Ghi County"]

  • ESRI_ADDRESS_SERVICE_AREA_VALIDATION_ATTRIBUTES is the list of attributes that should be checked in the response returned from the Esri service URL.

    Note that these attributes are custom for each Esri URL and you'll need to look at what fields are provided for your specific map to know what attribute to use. For example, Seattle's service area validation service specifies "CITYNAME" as an attribute.

    • Type: String[]

    • Example values: ["CITYNAME"], ["ZIPCODE"]

  • ESRI_ADDRESS_SERVICE_AREA_VALIDATION_IDS is the list of values that the attribute should be equal to in order for the address to be considered within the service area.

    • Type: String[]

    • Example values:

      • If _ATTRIBUTES is set to ["CITYNAME"], then _IDS could be set to ["Seattle"] in order to require addresses be in the city of Seattle.

      • If _ATTRIBUTES is set to ["ZIPCODE"], then _IDS could be set to ["28202"] in order to require addresses be in the 28202 zip code.

The configuration allows you to set up multiple service areas so that different questions can have different eligibility requirements. For example, maybe one program allows anyone in the county to apply while a different program only allows people in a certain zip code to apply. You can set up two service areas:

export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_URLS = ["arkansas-url", "neighborhood-url"]
export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_LABELS = ["Arkansas", "Example Neighborhood"]
export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_ATTRIBUTES = ["STATE", "ZIPCODE"]
export ESRI_ADDRESS_SERVICE_AREA_VALIDATION_IDS = ["AR", "01234"]

One program can set their eligibility condition to use "Arkansas" and the other program can set their eligibility condition to use "Example Neighborhood".

The arrays in each of these four variables should all be the same length. The values at index i should all correlate with each other. In the example above, all values at index 0 are for checking the county service area, and all values at index 1 are for checking the neighborhood service area.

Put another way:

  • When checking that an address is in the service area labeled "Arkansas" in the admin UI, CiviForm will query arkansas-url and check the response for a field called STATE with a value of "AR".

  • When checking that an address is in the service area labeled "Example Neighborhood" in the admin UI, CiviForm will query neighborhood-url and check the response for a field called ZIPCODE with a value of "01234".

Applying to questions

Once those configuration variables are set up, service area validation can be enabled or disabled on any address question using eligibility or visibility conditions:

Address correction must be enabled on the question before the eligibility or visibility conditions based on the service area can be set up.

Other configuration

ESRI_EXTERNAL_CALL_TRIES - Integer

The number of tries CiviForm will attempt requests to external Esri services.

Last updated