From 66c908913e224289485e3117e0b473eaa460c7da Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Thu, 14 Oct 2021 10:37:32 -0700 Subject: [PATCH] Run the area polygons in city.bin through the georust simplification. Seattle drops from 3MB to 800KB with no discernable loss of quality. --- data/MANIFEST.json | 54 +++++++++++++++++++++---------------------- geom/src/polygon.rs | 5 ++++ map_model/src/city.rs | 10 ++++++-- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/data/MANIFEST.json b/data/MANIFEST.json index 27c0e7e7b1..f05ee870f7 100644 --- a/data/MANIFEST.json +++ b/data/MANIFEST.json @@ -2461,9 +2461,9 @@ "compressed_size_bytes": 3827096 }, "data/system/at/salzburg/city.bin": { - "checksum": "e26ef4a68d4b63c1fe0d9529218cc84f", - "uncompressed_size_bytes": 693217, - "compressed_size_bytes": 421901 + "checksum": "1c0a87045a3c9eb40c1875fffcc98fcf", + "uncompressed_size_bytes": 202549, + "compressed_size_bytes": 96214 }, "data/system/at/salzburg/maps/east.bin": { "checksum": "caf18102dfc38bc42c2a03362791dff8", @@ -2506,9 +2506,9 @@ "compressed_size_bytes": 11641511 }, "data/system/ch/zurich/city.bin": { - "checksum": "a6b42ad0e987ecce87468abf72469437", - "uncompressed_size_bytes": 578592, - "compressed_size_bytes": 357426 + "checksum": "a209c74a10aa23d23feaf25e1c057efb", + "uncompressed_size_bytes": 156946, + "compressed_size_bytes": 73060 }, "data/system/ch/zurich/maps/center.bin": { "checksum": "c560f0906533100c3a6260457d9fdf9f", @@ -2581,9 +2581,9 @@ "compressed_size_bytes": 19085911 }, "data/system/fr/charleville_mezieres/city.bin": { - "checksum": "32a65b37219b93f2391b6bfe57950480", - "uncompressed_size_bytes": 187433, - "compressed_size_bytes": 115902 + "checksum": "29833aaa77dec950d0fd05e413d783e8", + "uncompressed_size_bytes": 54547, + "compressed_size_bytes": 29267 }, "data/system/fr/charleville_mezieres/maps/secteur1.bin": { "checksum": "36eaa21ed50483932f5dfc580a8f0cd4", @@ -2616,9 +2616,9 @@ "compressed_size_bytes": 31127978 }, "data/system/fr/paris/city.bin": { - "checksum": "776a26d6b917b8faaf15b90995d7c4b5", - "uncompressed_size_bytes": 2281178, - "compressed_size_bytes": 1374614 + "checksum": "1928619334effd967ad2488ba34ed2c9", + "uncompressed_size_bytes": 528230, + "compressed_size_bytes": 233651 }, "data/system/fr/paris/maps/center.bin": { "checksum": "4ff740ba65e93ac842908891417e851c", @@ -3281,9 +3281,9 @@ "compressed_size_bytes": 696607 }, "data/system/gb/leeds/city.bin": { - "checksum": "b1d557a7ffa14cda23b027fa8244353f", - "uncompressed_size_bytes": 1857120, - "compressed_size_bytes": 1139158 + "checksum": "bef0f06947cd4a8dd410c9ad45cb31fb", + "uncompressed_size_bytes": 560554, + "compressed_size_bytes": 273160 }, "data/system/gb/leeds/maps/central.bin": { "checksum": "699a31916eee6bec07ab7b2b15e7e8f8", @@ -3826,9 +3826,9 @@ "compressed_size_bytes": 14789895 }, "data/system/ir/tehran/city.bin": { - "checksum": "58ed8c751092a59a28685ab73bca10c5", - "uncompressed_size_bytes": 613751, - "compressed_size_bytes": 371230 + "checksum": "24b0f2ede5ebb1a483458a21ca349ade", + "uncompressed_size_bytes": 201435, + "compressed_size_bytes": 93099 }, "data/system/ir/tehran/maps/boundary0.bin": { "checksum": "c7a6afa1074279b89ef82c49ab5ee854", @@ -3951,9 +3951,9 @@ "compressed_size_bytes": 9163366 }, "data/system/us/mt_vernon/city.bin": { - "checksum": "173b2a66e9cdb9600e48e3c5f1506043", - "uncompressed_size_bytes": 197361, - "compressed_size_bytes": 109013 + "checksum": "6c1ccd19661e9bd33c55577e68f1c509", + "uncompressed_size_bytes": 37211, + "compressed_size_bytes": 22578 }, "data/system/us/mt_vernon/maps/burlington.bin": { "checksum": "4c35286d6d4da772ecfd238c7497e0c5", @@ -3966,9 +3966,9 @@ "compressed_size_bytes": 7426555 }, "data/system/us/nyc/city.bin": { - "checksum": "93f972082d026257625bd7bc10a45b63", - "uncompressed_size_bytes": 892706, - "compressed_size_bytes": 477936 + "checksum": "2d283a1ed31cba01ec51d723aa7e54ea", + "uncompressed_size_bytes": 245298, + "compressed_size_bytes": 103469 }, "data/system/us/nyc/maps/downtown_brooklyn.bin": { "checksum": "a0dc47209daedd2896360378871fc307", @@ -4011,9 +4011,9 @@ "compressed_size_bytes": 18918169 }, "data/system/us/seattle/city.bin": { - "checksum": "b147011af15d8dd38fbf9e3c90e29c7d", - "uncompressed_size_bytes": 3085409, - "compressed_size_bytes": 1952572 + "checksum": "5e1d2c772ac15649f8b4e52ae1ad4588", + "uncompressed_size_bytes": 769593, + "compressed_size_bytes": 390647 }, "data/system/us/seattle/maps/arboretum.bin": { "checksum": "8aac379cc6f1f0931561cf7334f6e1b0", diff --git a/geom/src/polygon.rs b/geom/src/polygon.rs index 31b0429991..35a4082b36 100644 --- a/geom/src/polygon.rs +++ b/geom/src/polygon.rs @@ -5,6 +5,7 @@ use anyhow::Result; use geo::algorithm::area::Area; use geo::algorithm::convex_hull::ConvexHull; use geo::algorithm::intersects::Intersects; +use geo::algorithm::simplifyvw::SimplifyVWPreserve; use geo_booleanop::boolean::BooleanOp; use serde::{Deserialize, Serialize}; @@ -544,6 +545,10 @@ impl Polygon { } Ok(results) } + + pub fn simplify(&self, epsilon: f64) -> Polygon { + to_geo(self.points()).simplifyvw_preserve(&epsilon).into() + } } impl fmt::Display for Polygon { diff --git a/map_model/src/city.rs b/map_model/src/city.rs index 3a2b7aa4b1..1e1249ae8f 100644 --- a/map_model/src/city.rs +++ b/map_model/src/city.rs @@ -6,6 +6,9 @@ use geom::{GPSBounds, LonLat, Polygon, Ring}; use crate::{AreaType, Map}; +// Hand-tuned. I think this is in units of meters? +const POLYGON_EPSILON: f64 = 1000.0; + /// A single city (like Seattle) can be broken down into multiple boundary polygons (udistrict, /// ballard, downtown, etc). The load map screen uses this struct to display the entire city. #[derive(Serialize, Deserialize)] @@ -46,7 +49,7 @@ impl City { areas: huge_map .all_areas() .iter() - .map(|a| (a.area_type, a.polygon.clone())) + .map(|a| (a.area_type, a.polygon.simplify(POLYGON_EPSILON))) .collect(), districts, } @@ -99,7 +102,10 @@ impl City { let pts = map.gps_bounds.convert_back(area.polygon.points()); // TODO Holes in the polygons get lost if let Ok(ring) = Ring::new(gps_bounds.convert(&pts)) { - areas.push((area.area_type, ring.into_polygon())); + areas.push(( + area.area_type, + ring.into_polygon().simplify(POLYGON_EPSILON), + )); } } }