Saving current working state before proceeding to Stage 2. Includes: - Backend: Python-based QC validator with shapefile processing - Frontend: Drag-and-drop file upload interface - Sample files for testing - Documentation and revision history 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
370 lines
15 KiB
SQL
370 lines
15 KiB
SQL
-- Test data for zones (info layer) and sites (home points)
|
|
-- This creates zone polygons and site points for testing zone containment QC features
|
|
-- Coordinates match the existing segment data from test_data.sql
|
|
|
|
-- ============================================
|
|
-- CREATE TABLES
|
|
-- ============================================
|
|
|
|
-- Create info table for zone polygons
|
|
CREATE TABLE IF NOT EXISTS eli_test.info (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR,
|
|
tags VARCHAR,
|
|
description VARCHAR,
|
|
group_1 VARCHAR,
|
|
group_2 VARCHAR,
|
|
mapprojectid INTEGER,
|
|
geom GEOMETRY(Polygon, 6561)
|
|
);
|
|
|
|
-- Create sites table for home points
|
|
CREATE TABLE IF NOT EXISTS eli_test.sites (
|
|
gid SERIAL PRIMARY KEY,
|
|
id INTEGER,
|
|
mapprojectid INTEGER,
|
|
longitude VARCHAR,
|
|
latitude VARCHAR,
|
|
exclude INTEGER,
|
|
custom INTEGER,
|
|
color VARCHAR,
|
|
opacity VARCHAR,
|
|
shapeid VARCHAR,
|
|
stylesize VARCHAR,
|
|
createdby INTEGER,
|
|
createddate INTEGER,
|
|
modifiedby INTEGER,
|
|
modifieddate INTEGER,
|
|
historyid INTEGER,
|
|
name VARCHAR,
|
|
statusid INTEGER,
|
|
group1 VARCHAR,
|
|
group2 VARCHAR,
|
|
icontypeid INTEGER,
|
|
schoolid VARCHAR,
|
|
sitedemarc VARCHAR,
|
|
address1 VARCHAR,
|
|
address2 VARCHAR,
|
|
city VARCHAR,
|
|
state VARCHAR,
|
|
zip VARCHAR,
|
|
geom GEOMETRY(Point, 6561)
|
|
);
|
|
|
|
-- ============================================
|
|
-- INSERT ZONE POLYGONS (INFO LAYER)
|
|
-- ============================================
|
|
|
|
-- Zone_A: Large zone covering most of the test segments
|
|
-- Covers approximately -122.43 to -122.41 longitude, 37.77 to 37.82 latitude
|
|
INSERT INTO eli_test.info (name, description, group_1, mapprojectid, geom)
|
|
VALUES
|
|
('Zone_A', 'Primary test zone covering most network elements', 'Zone_A', 1,
|
|
ST_Transform(ST_GeomFromText('POLYGON((
|
|
-122.4350 37.7700,
|
|
-122.4100 37.7700,
|
|
-122.4100 37.8200,
|
|
-122.4350 37.8200,
|
|
-122.4350 37.7700
|
|
))', 4326), 6561)),
|
|
|
|
-- Zone_B: Smaller zone for Zone_B segments
|
|
-- Covers approximately -122.41 to -122.406 longitude, 37.784 to 37.789 latitude
|
|
('Zone_B', 'Secondary test zone for Zone_B network elements', 'Zone_B', 1,
|
|
ST_Transform(ST_GeomFromText('POLYGON((
|
|
-122.4100 37.7840,
|
|
-122.4060 37.7840,
|
|
-122.4060 37.7890,
|
|
-122.4100 37.7890,
|
|
-122.4100 37.7840
|
|
))', 4326), 6561)),
|
|
|
|
-- Zone_C: Another zone for Zone_C segments
|
|
-- Covers approximately -122.40 to -122.397 longitude, 37.794 to 37.798 latitude
|
|
('Zone_C', 'Tertiary test zone for Zone_C network elements', 'Zone_C', 1,
|
|
ST_Transform(ST_GeomFromText('POLYGON((
|
|
-122.4000 37.7940,
|
|
-122.3970 37.7940,
|
|
-122.3970 37.7980,
|
|
-122.4000 37.7980,
|
|
-122.4000 37.7940
|
|
))', 4326), 6561)),
|
|
|
|
-- Zone_D: Small zone with no network elements (for testing edge cases)
|
|
('Zone_D', 'Empty zone with no network elements', 'Zone_D', 1,
|
|
ST_Transform(ST_GeomFromText('POLYGON((
|
|
-122.3900 37.7600,
|
|
-122.3850 37.7600,
|
|
-122.3850 37.7650,
|
|
-122.3900 37.7650,
|
|
-122.3900 37.7600
|
|
))', 4326), 6561));
|
|
|
|
-- ============================================
|
|
-- INSERT SITES (HOME POINTS)
|
|
-- ============================================
|
|
|
|
-- Sites in Zone_A (correctly within the zone)
|
|
INSERT INTO eli_test.sites (id, mapprojectid, name, address1, city, state, zip, group1, geom)
|
|
VALUES
|
|
-- Site near the aerial segment chain
|
|
(1001, 1, 'Home-1001', '123 Market St', 'San Francisco', 'CA', '94102', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4190 37.7755)', 4326), 6561)),
|
|
|
|
(1002, 1, 'Home-1002', '456 Mission St', 'San Francisco', 'CA', '94103', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4175 37.7765)', 4326), 6561)),
|
|
|
|
(1003, 1, 'Home-1003', '789 Howard St', 'San Francisco', 'CA', '94103', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4160 37.7775)', 4326), 6561)),
|
|
|
|
-- Site near underground segments
|
|
(1004, 1, 'Home-1004', '321 Folsom St', 'San Francisco', 'CA', '94107', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4150 37.7785)', 4326), 6561)),
|
|
|
|
-- Site near the long aerial segment
|
|
(1005, 1, 'Home-1005', '555 Bryant St', 'San Francisco', 'CA', '94107', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4200 37.7710)', 4326), 6561)),
|
|
|
|
-- Sites near poles
|
|
(1006, 1, 'Home-1006', '888 Harrison St', 'San Francisco', 'CA', '94107', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4205 37.7805)', 4326), 6561)),
|
|
|
|
-- Site near branching segments
|
|
(1007, 1, 'Home-1007', '999 7th St', 'San Francisco', 'CA', '94103', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4135 37.7735)', 4326), 6561)),
|
|
|
|
(1008, 1, 'Home-1008', '111 8th St', 'San Francisco', 'CA', '94103', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4125 37.7745)', 4326), 6561)),
|
|
|
|
-- Additional sites in Zone_A
|
|
(1009, 1, 'Home-1009', '222 9th St', 'San Francisco', 'CA', '94103', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4330 37.7685)', 4326), 6561)),
|
|
|
|
(1010, 1, 'Home-1010', '333 10th St', 'San Francisco', 'CA', '94103', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4325 37.7695)', 4326), 6561)),
|
|
|
|
-- Sites near edges of Zone_A (still valid)
|
|
(1011, 1, 'Home-1011', '444 11th St', 'San Francisco', 'CA', '94103', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4105 37.7750)', 4326), 6561)),
|
|
|
|
(1012, 1, 'Home-1012', '666 Townsend St', 'San Francisco', 'CA', '94107', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4340 37.7720)', 4326), 6561)),
|
|
|
|
-- Sites in Zone_B (correctly within the zone)
|
|
(2001, 1, 'Home-2001', '100 Oak St', 'San Francisco', 'CA', '94102', 'Zone_B',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4090 37.7855)', 4326), 6561)),
|
|
|
|
(2002, 1, 'Home-2002', '200 Fell St', 'San Francisco', 'CA', '94102', 'Zone_B',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4078 37.7865)', 4326), 6561)),
|
|
|
|
(2003, 1, 'Home-2003', '300 Hayes St', 'San Francisco', 'CA', '94102', 'Zone_B',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4070 37.7875)', 4326), 6561)),
|
|
|
|
-- Sites in Zone_C (correctly within the zone)
|
|
(3001, 1, 'Home-3001', '400 Grove St', 'San Francisco', 'CA', '94117', 'Zone_C',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.3990 37.7955)', 4326), 6561)),
|
|
|
|
(3002, 1, 'Home-3002', '500 Fulton St', 'San Francisco', 'CA', '94117', 'Zone_C',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.3980 37.7965)', 4326), 6561)),
|
|
|
|
-- ============================================
|
|
-- INVALID TEST CASES: Sites OUTSIDE their assigned zones
|
|
-- ============================================
|
|
|
|
-- Site with group1='Zone_A' but physically located in Zone_B
|
|
(1013, 1, 'Home-1013-INVALID', '777 Invalid Location', 'San Francisco', 'CA', '94102', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4080 37.7860)', 4326), 6561)),
|
|
|
|
-- Site with group1='Zone_B' but physically located in Zone_A
|
|
(2004, 1, 'Home-2004-INVALID', '888 Wrong Zone', 'San Francisco', 'CA', '94103', 'Zone_B',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4200 37.7750)', 4326), 6561)),
|
|
|
|
-- Site with group1='Zone_C' but physically located outside all zones
|
|
(3003, 1, 'Home-3003-INVALID', '999 Outside All Zones', 'San Francisco', 'CA', '94110', 'Zone_C',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.3800 37.7500)', 4326), 6561)),
|
|
|
|
-- Site with group1='Zone_A' but physically outside all zones
|
|
(1014, 1, 'Home-1014-INVALID', '1111 Far Away', 'San Francisco', 'CA', '94110', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.3700 37.7400)', 4326), 6561)),
|
|
|
|
-- Site with NULL group1 (unassigned) but inside Zone_A
|
|
(1015, 1, 'Home-1015-UNASSIGNED', '1212 Unassigned St', 'San Francisco', 'CA', '94103', NULL,
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4250 37.7800)', 4326), 6561)),
|
|
|
|
-- Site with group1='Zone_D' (correctly in Zone_D, but Zone_D has no network)
|
|
(4001, 1, 'Home-4001', '1313 Empty Zone', 'San Francisco', 'CA', '94110', 'Zone_D',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.3875 37.7625)', 4326), 6561));
|
|
|
|
-- ============================================
|
|
-- ADD SOME POLES AND ACCESS POINTS OUTSIDE THEIR ZONES FOR TESTING
|
|
-- ============================================
|
|
|
|
-- Pole with group1='Zone_A' but physically in Zone_B (INVALID)
|
|
INSERT INTO eli_test.poles (id, mapprojectid, name, owner, poleheight, attachmentheight, group1, geom)
|
|
VALUES
|
|
(201, 1, 'Pole-201-INVALID', 'Test Utility', '40', '35', 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4085 37.7850)', 4326), 6561)),
|
|
|
|
-- Pole with group1='Zone_B' but physically in Zone_C (INVALID)
|
|
(202, 1, 'Pole-202-INVALID', 'Test Utility', '40', '35', 'Zone_B',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.3985 37.7960)', 4326), 6561)),
|
|
|
|
-- Pole with group1='Zone_C' but outside all zones (INVALID)
|
|
(203, 1, 'Pole-203-INVALID', 'Test Utility', '40', '35', 'Zone_C',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.3600 37.7300)', 4326), 6561));
|
|
|
|
-- Access point with group1='Zone_A' but physically in Zone_B (INVALID)
|
|
INSERT INTO eli_test.access_points (id, name, mapprojectid, description, manufacturer, size, typeid, statusid, group1, geom)
|
|
VALUES
|
|
(301, 'Handhole-301-INVALID', 1, 'Misplaced handhole', 'CommScope', '24x36', 1, 1, 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.4075 37.7870)', 4326), 6561)),
|
|
|
|
-- Access point with group1='Zone_B' but outside all zones (INVALID)
|
|
(302, 'Handhole-302-INVALID', 1, 'Outside zone handhole', 'CommScope', '24x36', 1, 1, 'Zone_B',
|
|
ST_Transform(ST_GeomFromText('POINT(-122.3500 37.7200)', 4326), 6561));
|
|
|
|
-- ============================================
|
|
-- TEST SEGMENTS THAT CROSS ZONE BOUNDARIES
|
|
-- ============================================
|
|
|
|
-- These segments test the scenario where a segment is PARTIALLY in its assigned zone
|
|
-- According to requirements, these should NOT be flagged as invalid
|
|
|
|
INSERT INTO eli_test.segment2 (type, length, cost, fdh_id, "Group 1", geom)
|
|
VALUES
|
|
-- VALID: Segment tagged Zone_A that starts in Zone_A and crosses into Zone_B
|
|
-- Starts at -122.4110 (in Zone_A) and ends at -122.4070 (in Zone_B)
|
|
('Aerial', 450.0, 4500.00, 1, 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('LINESTRING(-122.4110 37.7850, -122.4070 37.7860)', 4326), 6561)),
|
|
|
|
-- VALID: Another segment tagged Zone_A that crosses into Zone_B
|
|
('Underground', 380.0, 7600.00, 1, 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('LINESTRING(-122.4120 37.7855, -122.4065 37.7865)', 4326), 6561)),
|
|
|
|
-- INVALID: Segment tagged Zone_A but COMPLETELY in Zone_B (no part in Zone_A)
|
|
('Aerial', 145.0, 1450.00, 1, 'Zone_A',
|
|
ST_Transform(ST_GeomFromText('LINESTRING(-122.4095 37.7855, -122.4085 37.7865)', 4326), 6561)),
|
|
|
|
-- INVALID: Segment with NULL/blank "Group 1" (should be flagged)
|
|
('Aerial', 150.0, 1500.00, 1, NULL,
|
|
ST_Transform(ST_GeomFromText('LINESTRING(-122.4200 37.7780, -122.4190 37.7790)', 4326), 6561)),
|
|
|
|
-- INVALID: Another segment with NULL/blank "Group 1"
|
|
('Underground', 140.0, 2800.00, 1, NULL,
|
|
ST_Transform(ST_GeomFromText('LINESTRING(-122.4180 37.7785, -122.4170 37.7795)', 4326), 6561)),
|
|
|
|
-- VALID: Segment that crosses from Zone_B into area outside defined zones, but partially in Zone_B
|
|
('Aerial', 500.0, 5000.00, 2, 'Zone_B',
|
|
ST_Transform(ST_GeomFromText('LINESTRING(-122.4080 37.7860, -122.4050 37.7870)', 4326), 6561)),
|
|
|
|
-- INVALID: Segment tagged Zone_C but completely outside all zones
|
|
('Underground', 200.0, 4000.00, 3, 'Zone_C',
|
|
ST_Transform(ST_GeomFromText('LINESTRING(-122.3600 37.7300, -122.3580 37.7310)', 4326), 6561));
|
|
|
|
-- ============================================
|
|
-- VERIFICATION QUERIES
|
|
-- ============================================
|
|
|
|
-- Verify zone polygons were inserted
|
|
SELECT COUNT(*) as total_zones FROM eli_test.info;
|
|
SELECT id, name, group_1, ST_AsText(ST_Transform(geom, 4326)) as polygon_wkt FROM eli_test.info ORDER BY id;
|
|
|
|
-- Verify sites were inserted
|
|
SELECT COUNT(*) as total_sites FROM eli_test.sites;
|
|
SELECT id, name, group1, ST_AsText(ST_Transform(geom, 4326)) as location FROM eli_test.sites ORDER BY id;
|
|
|
|
-- Check which sites are VALID (inside their assigned zone)
|
|
SELECT
|
|
s.id,
|
|
s.name,
|
|
s.group1 as assigned_zone,
|
|
i.group_1 as actual_zone,
|
|
CASE
|
|
WHEN s.group1 = i.group_1 THEN 'VALID'
|
|
ELSE 'INVALID'
|
|
END as status
|
|
FROM eli_test.sites s
|
|
LEFT JOIN eli_test.info i ON ST_Within(s.geom, i.geom)
|
|
ORDER BY s.id;
|
|
|
|
-- Check which poles are VALID (inside their assigned zone)
|
|
SELECT
|
|
p.id,
|
|
p.name,
|
|
p.group1 as assigned_zone,
|
|
i.group_1 as actual_zone,
|
|
CASE
|
|
WHEN p.group1 = i.group_1 THEN 'VALID'
|
|
ELSE 'INVALID'
|
|
END as status
|
|
FROM eli_test.poles p
|
|
LEFT JOIN eli_test.info i ON ST_Within(p.geom, i.geom)
|
|
WHERE p.id >= 201 -- Only check the new test poles we added
|
|
ORDER BY p.id;
|
|
|
|
-- Check which access points are VALID (inside their assigned zone)
|
|
SELECT
|
|
ap.id,
|
|
ap.name,
|
|
ap.group1 as assigned_zone,
|
|
i.group_1 as actual_zone,
|
|
CASE
|
|
WHEN ap.group1 = i.group_1 THEN 'VALID'
|
|
ELSE 'INVALID'
|
|
END as status
|
|
FROM eli_test.access_points ap
|
|
LEFT JOIN eli_test.info i ON ST_Within(ap.geom, i.geom)
|
|
WHERE ap.id >= 301 -- Only check the new test access points we added
|
|
ORDER BY ap.id;
|
|
|
|
-- Count sites by zone assignment
|
|
SELECT group1, COUNT(*) as site_count
|
|
FROM eli_test.sites
|
|
GROUP BY group1
|
|
ORDER BY group1;
|
|
|
|
-- ============================================
|
|
-- TEST SCENARIO SUMMARY
|
|
-- ============================================
|
|
|
|
/*
|
|
ZONE POLYGONS:
|
|
- Zone_A: Large polygon covering most test segments (37.77-37.82, -122.435--122.41)
|
|
- Zone_B: Smaller polygon for Zone_B segments (37.784-37.789, -122.41--122.406)
|
|
- Zone_C: Small polygon for Zone_C segments (37.794-37.798, -122.40--122.397)
|
|
- Zone_D: Empty zone with no network elements (for edge case testing)
|
|
|
|
SITES (HOME POINTS):
|
|
- Valid sites in Zone_A: 12 sites correctly within Zone_A polygon
|
|
- Valid sites in Zone_B: 3 sites correctly within Zone_B polygon
|
|
- Valid sites in Zone_C: 2 sites correctly within Zone_C polygon
|
|
- Valid sites in Zone_D: 1 site correctly within Zone_D polygon
|
|
- Invalid sites (wrong zone): 4 sites with group1 not matching actual zone location
|
|
- Unassigned site: 1 site with NULL group1
|
|
|
|
TOTAL SITES: 23 sites (18 valid, 4 invalid, 1 unassigned)
|
|
|
|
INVALID NETWORK ELEMENTS FOR ZONE QC:
|
|
- Poles: 3 poles with group1 not matching their zone location
|
|
- Access Points: 2 access points with group1 not matching their zone location
|
|
|
|
SEGMENTS THAT CROSS ZONE BOUNDARIES:
|
|
- Valid (partially in assigned zone): 3 segments that cross boundaries but have some part in their assigned zone
|
|
- Invalid (completely outside assigned zone): 2 segments tagged for a zone but completely in a different zone
|
|
- Invalid (NULL/blank zone): 2 segments with NULL "Group 1" attribute
|
|
|
|
QC TEST SCENARIOS THIS ENABLES:
|
|
1. Verify sites are within their assigned zones
|
|
2. Verify poles are within their assigned zones
|
|
3. Verify access points are within their assigned zones
|
|
4. Verify segments are within their assigned zones (segments have "Group 1" column)
|
|
5. DO NOT flag segments that are PARTIALLY in their assigned zone (crossing boundaries is OK)
|
|
6. DO flag segments that are COMPLETELY outside their assigned zone
|
|
7. DO flag any network element with NULL/blank zone attribute
|
|
8. Detect network elements outside all zones
|
|
9. Handle zones with no network elements (Zone_D)
|
|
10. Detect mismatches between assigned zone and physical location
|
|
|
|
All test data uses mapprojectid=1 for consistency
|
|
*/
|