Demo · 7 September 2026
Settlements UI
React, MobX and a MapLibre map. Vertex editing, bulk polygon import and GeoJSON export. The dataset has 54 Russian territories: 19 cities, 27 districts and municipal areas, and 8 regions. Boundaries come from OpenStreetMap. The backend is mocked; edits stay in tab memory.
01 / The task
Polygon editor with GeoJSON import
Each object has a record and geometry on the map. Both need to stay in sync. Bulk import validates geometry, shows errors and applies only valid polygons.
Use case: Editing city, district and other territorial boundaries.
Work done
- Object records, map layers and geometry editing.
- React/MobX integration with MapLibre and Mapbox Draw. Geometry import and export.
- Added a demo adapter in place of the corporate API. Removed production data and private registry dependencies.
- Deployment, layout fixes, bulk import checks and an OpenStreetMap boundary dataset.
Screenshots
Screens, forms, errorsScreenshots, diagrams and source evidence retain their original language; captions and descriptions are translated.
02 / Technology
Stack
React / MobX
Original screens, state and import
MapLibre / Mapbox Draw
Map basemap, layers and geometry editing
GeoJSON / WKB
Validation, upload and export
03 / Decisions
How the project works
- The original sppi-dark theme: dark background, yellow controls and original status colors.
- MapLibre loads standard OpenStreetMap tiles. Attribution is included; bulk map downloads and offline caching are not implemented.
- The original FilesScreen → PolygonsScreen → PolygonEditScreen flow runs through a local adapter for OData and geo-import contracts.
- Imports are validated and previewed first. Applying an import transfers only valid polygons to the main editor; applying it again does not duplicate the same importId.
- Standalone styles share the .sppi-dark scope: original colors, consistent SVG icons, 40 px actions and responsive file cards. ResizeObserver keeps MapLibre in sync with panel and viewport changes.
- OpenStreetMap outlines are simplified with topology preserved: 54 territories, 21,421 vertices and 7 MultiPolygons. Regions, districts and cities have different opacity; original control and status colors are preserved.
04 / Verification
Demo workflows
- Find Vladimir, Suzdal, Nizhny Novgorod, Suzdalsky District or Vladimir Oblast; open its record and zoom to the outline.
- Download the 54-territory dataset, upload it through bulk import and validate all geometries.
- Open a file: polygon list, statuses, filters and a map of the combined boundaries.
- Open a polygon: edit it, restore the original geometry, explicitly skip it and save.
- Fix or skip errors, select “Apply import”, close the module and export the result from the main editor.
- Reset the example; check that another tab did not receive the imported files.
Check results
- The static build is served by shared Nginx; GIS has no separate backend process on the VPS.
- 54 objects; 21,421 vertices after simplification, 76–926 per object, up to 480 per ring. These describe the dataset, not boundary accuracy.
- In one Chromium check of the published version: first list 1.80 s, import of 54 territories 0.66 s. This measures the interface on the test machine; it is not a load test or an SLA.
Limitations
- Only the backend is replaced with tab memory. The server-side OData/PostGIS service is not connected; the original repository remains private.
- Adapter limits: 20 files, 500 polygons per file, 1,000 per session; file text up to 5 MB. Polygon/MultiPolygon and EPSG:4326/3857 are supported.
- Imported data disappears after reloading. GeoJSON export lets you save the result locally.
- OpenStreetMap tiles load from an external server. The basemap needs that server to be available.
- OSM boundaries are simplified for editing and are not cadastral data. Cities use place=city/town outlines; districts and regions use boundary=administrative. OKTMO codes are for demonstration. The source and ODbL license are stated in the demo and downloadable GeoJSON.
Technical notes
Modules, API, data model, setup and check results.
Documentation →Materials ↓