# Routing Customization

> Route customization requests to the correct subskills. Use when: changing location, changing map, changing vehicle, changing routing profile. Do NOT use for: initial ORS deployment (use install-fleet-apps), deploying demo apps, or reading ORS config only (use read-ors-configuration subskill directly). Triggers: change location, change map, change vehicle, change routing profile, change routing profiles.

- Skill: `snowflake-labs/routing-customization` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add snowflake-labs/routing-customization`
- Raw SKILL.md: https://api.skillmd.com/api/skills/snowflake-labs/routing-customization/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: snowflake-labs (https://skillmd.com/u/snowflake-labs)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/snowflake-labs/routing-customization

---


# Customization Router

This skill routes customization requests to the correct subskills based on what you want to customize.

## Configuration

| Parameter | Default | Description |
|-----------|---------|-------------|
| `ORS_APP_NAME` | `OPENROUTESERVICE_APP` | Name of the installed ORS app |
| `COMPUTE_POOL` | `OPENROUTESERVICE_APP_COMPUTE_POOL` | Compute pool used by ORS services |
| `MAP_REGION` | (current) | Target geographic region for the map data |
| `ROUTING_PROFILES` | (current) | Comma-separated list of profiles to enable |

## Required Privileges

| Privilege | Scope | Reason |
|-----------|-------|--------|
| USAGE ON DATABASE OPENROUTESERVICE_APP | DATABASE | Reads and modifies ORS configuration |
| ALTER COMPUTE POOL | Compute Pool | Suspends/resumes compute pool for config changes |
| ALTER SERVICE | Application | Suspends/resumes ORS services and updates specs |
| INSERT/DELETE ON OPENROUTESERVICE_APP.CORE.MAP_CONFIG | Table | Updates map configuration for Function Tester |

## Error Logging

> Follow the Error Logging convention in AGENTS.md. Log file prefix: `routing-customization`.

## Workflow

> All file paths in subskills (e.g., `.cortex/skills/install-fleet-apps/openrouteservice_app/...`) are relative to the repository root directory.

### Query Tag

Set at the start of every session:

```sql
ALTER SESSION SET query_tag = '{"origin":"sf_sit-is-fleet","name":"oss-routing-customization","version":{"major":1,"minor":0},"attributes":{"is_quickstart":1,"source":"sql"}}';
```

### Step 1: Read Initial ORS Configuration and Gather Customization Options

**Goal:** Detect the initial map region and routing profiles from the ORS configuration and display to the user

> Read and follow the instructions in `.cortex/skills/routing-customization/read-ors-configuration/SKILL.md`

**Output:** ORS configuration displayed to the user:
- Initially configured Map Region: `<INITIAL_REGION_NAME>`
- Initially configured Vehicle profiles: `<INITIAL_PROFILES>`

### Step 2: Determine What to Customize

**Ask the user (allow multiple selections):**

"What would you like to customize? Multiple selection is allowed."

1. **Location/Map** - Change the geographic region (e.g., San Francisco → Paris)
2. **Routing Profiles** - Enable/disable routing profiles (driving-car, driving-hgv, cycling-electric)

**IMPORTANT:** Use multi-select so the user can choose one or both options. If both are selected, run the location skill first, then the routing profiles skill, before proceeding to Step 4.

### Step 3: Route to Correct Skill

**If user wants to change LOCATION or MAP:**

> This requires changing a map. 
> Read and follow the instructions in `.cortex/skills/routing-customization/location/SKILL.md`

**If user wants to change ROUTING PROFILES:**

> This updates which routing profiles are available.
> Read and follow the instructions in `.cortex/skills/routing-customization/routing-profiles/SKILL.md`

### Step 4: Update Routing Graphs

**Goal:** Restart services to update routing graphs with new location

**Actions:**

1. **Determine if this is a new region or an existing region re-download:**

   - **New region** (no prior graphs exist): Skip the REMOVE commands and proceed directly to resuming services. The graphs stage paths won't exist yet.
   
   - **Existing region re-download** (map existed and user selected to re-download): Ask the user:
     - "Do you want to rebuild the routing graphs for this region? This will clear existing cached graphs and elevation data, forcing a fresh rebuild."

2. **If existing region and user confirms YES**, clear existing graphs and elevation cache:
   ```sql
   REMOVE @OPENROUTESERVICE_APP.CORE.ORS_ELEVATION_CACHE_SPCS_STAGE/<REGION_NAME>/;
   REMOVE @OPENROUTESERVICE_APP.CORE.ORS_GRAPHS_SPCS_STAGE/<REGION_NAME>/;
   ```
   
   > **_NOTE:_** This ensures graphs are rebuilt from scratch with the new map data rather than using potentially stale cached data.

3. **Resume** the compute pool (required if it was suspended during location change):
   ```sql
   ALTER COMPUTE POOL OPENROUTESERVICE_APP_COMPUTE_POOL RESUME;
   ```

4. **Resume** all services:
   ```sql
   CALL OPENROUTESERVICE_APP.CORE.RESUME_ALL_SERVICES();
   ```

5. **Verify** ORS is healthy:
   ```sql
   SELECT OPENROUTESERVICE_APP.CORE.CHECK_HEALTH();
   ```

6. **Monitor** ORS_SERVICE logs for graph building progress:
   ```sql
   CALL SYSTEM$GET_SERVICE_LOGS('OPENROUTESERVICE_APP.CORE.ORS_SERVICE', 0, 'ors', 100);
   ```
   - Look for: `"Graph built in X seconds"` messages for each enabled profile

**Note:** Graph building can take 30 minutes to several hours depending on map size and number of enabled profiles.

**Output:** Services rebuilding with new map

### Step 5: Update MAP_CONFIG Table

**Goal:** Store map configuration so Function Tester can dynamically load settings

**Actions:**

1. **Clear** any existing configuration:
   ```sql
   DELETE FROM OPENROUTESERVICE_APP.CORE.MAP_CONFIG;
   ```

2. **Insert** the new map configuration:
   ```sql
   INSERT INTO OPENROUTESERVICE_APP.CORE.MAP_CONFIG 
   (city_name, center_lat, center_lon, min_lat, max_lat, min_lon, max_lon, osm_file_name, updated_at)
   VALUES ('<CITY_NAME>', <CENTER_LAT>, <CENTER_LON>, <MIN_LAT>, <MAX_LAT>, <MIN_LON>, <MAX_LON>, '<MAP_NAME>', CURRENT_TIMESTAMP());
   ```
   
   > **_NOTE:_** The `updated_at` column is required -- the Function Tester uses `ORDER BY updated_at DESC LIMIT 1` to load the latest config.
   
   **Example for Paris:**
   ```sql
   INSERT INTO OPENROUTESERVICE_APP.CORE.MAP_CONFIG 
   (city_name, center_lat, center_lon, min_lat, max_lat, min_lon, max_lon, osm_file_name, updated_at)
   VALUES ('Paris', 48.8566, 2.3522, 48.80, 48.92, 2.22, 2.42, 'Paris.osm.pbf', CURRENT_TIMESTAMP());
   ```
   
   **Example for Berlin:**
   ```sql
   INSERT INTO OPENROUTESERVICE_APP.CORE.MAP_CONFIG 
   (city_name, center_lat, center_lon, min_lat, max_lat, min_lon, max_lon, osm_file_name, updated_at)
   VALUES ('Berlin', 52.5200, 13.4050, 52.35, 52.70, 13.08, 13.77, 'Berlin.osm.pbf', CURRENT_TIMESTAMP());
   ```

3. **Verify** the configuration was saved:
   ```sql
   SELECT * FROM OPENROUTESERVICE_APP.CORE.MAP_CONFIG;
   ```

**Note:** The Function Tester will automatically generate test addresses within these bounds when it loads. If no MAP_CONFIG entry exists, it defaults to San Francisco.

**Output:** MAP_CONFIG table updated with new region bounds

### Step 6: Redeploy SPCS APP

**Goal:** Upload and redeploy the Function Tester so it picks up the new MAP_CONFIG

**Note:** The Function Tester automatically reads the MAP_CONFIG table (updated in Step 5) and dynamically generates region-specific sample addresses within those bounds. No manual code edits are needed for addresses - just redeploy.

> **_NOTE:_** The React-based Function Tester in the ORS Control App dynamically loads installed profiles from ORS_STATUS - no hardcoded profile list to update.

**Actions:**

1. Follow instructions from AGENT.MD to deploy new ors control app

**Output:** Function Tester redeployed, now showing addresses for the new region

## Examples

### Example 1: Change location from San Francisco to Paris
User says: "Change the map to Paris"
Actions:
1. Read current ORS configuration (Step 1)
2. Route to location subskill (Step 3)
3. Download Paris city map from BBBike, upload to stage
4. Update routing graphs (Step 4), MAP_CONFIG (Step 5), redeploy Function Tester (Step 6)
Result: ORS serves routes for Paris, Function Tester shows Paris addresses

### Example 2: Enable additional routing profiles
User says: "Add walking and cycling-regular profiles"
Actions:
1. Read current ORS configuration (Step 1)
2. Route to routing-profiles subskill (Step 3)
3. Call WRITE_ORS_CONFIG with updated profile list
4. Rebuild routing graphs (Step 4)
Result: ORS serves routes for walking, cycling-regular, and previously enabled profiles

### Example 3: Change both location and profiles
User says: "Switch to London with driving-car and foot-walking only"
Actions:
1. Read current ORS configuration (Step 1)
2. User selects both Location and Routing Profiles (Step 2)
3. Run location subskill first, then routing-profiles subskill (Step 3)
4. Rebuild graphs, update MAP_CONFIG, redeploy Function Tester (Steps 4-6)
Result: ORS serves London routes for driving-car and foot-walking

## Stopping Points

- ✋ After Step 3: Confirm map download completed
- ✋ After Step 4: Verify services are rebuilding graphs
- ✋ After Step 5: Verify MAP_CONFIG table has correct bounds
- ✋ After Step 6: Verify Function Tester shows new region addresses

## Cleanup

This skill modifies ORS configuration but does not create persistent objects. To revert changes:

1. Re-run the location subskill to change back to the original region
2. Re-run the routing-profiles subskill to restore original profile settings
3. Restart services via Step 4

> **Tip:** Use the `cleanup` skill to auto-discover all tagged objects via COMMENT tracking.
