From 777f05b6a038faa3ab8c0ebc3259fb3961f82b14 Mon Sep 17 00:00:00 2001 From: Max Duval Date: Thu, 16 May 2024 07:25:07 +0100 Subject: [PATCH] feat: add POIs --- src/components/LooMap/LooMap.tsx | 339 +++++++++++++++++-------------- 1 file changed, 187 insertions(+), 152 deletions(-) diff --git a/src/components/LooMap/LooMap.tsx b/src/components/LooMap/LooMap.tsx index 9c39bf8bb..f0bc2cefb 100644 --- a/src/components/LooMap/LooMap.tsx +++ b/src/components/LooMap/LooMap.tsx @@ -20,7 +20,11 @@ import ZoomControl from './ZoomControl'; import crosshairSvg from '../../../public/crosshair.svg'; import { CenteredTextSymbolizer, - // PolygonSymbolizer, + CircleSymbolizer, + GroupSymbolizer, + Justify, + OffsetTextSymbolizer, + TextPlacements, labelRules, leafletLayer, paintRules, @@ -114,158 +118,189 @@ const LooMap: React.FC = ({ // Free for non-commercial use https://protomaps.com/ url: 'https://api.protomaps.com/tiles/v3/{z}/{x}/{y}.mvt?key=73e8a482f059f3f5', paintRules: paintRules(mapTheme), - labelRules: labelRules(mapTheme).concat({ - dataLayer: 'pois', - symbolizer: new CenteredTextSymbolizer({ - labelProps: (z) => (z < 6 ? ['name:short'] : ['name']), - fill: '#0a165e', - stroke: '#f4f4f4', - width: 1, - lineHeight: 1.5, - font: '400 14px', - }), - filter: (z, { props }) => { - return z > 14; - [ - 'aerodrome', - 'adult_gaming_centre', - 'airfield', - 'alpine_hut', - 'amusement_ride', - 'animal', - 'art', - 'artwork', - 'atm', - 'attraction', - 'atv', - 'baby_hatch', - 'bakery', - 'bbq', - 'beauty', - 'bed_and_breakfast', - 'bench', - 'bicycle_parking', - 'bicycle_rental', - 'bicycle_repair_station', - 'boat_storage', - 'bookmaker', - 'books', - 'bureau_de_change', - 'bus_stop', - 'butcher', - 'cafe', - 'camp_site', - 'car_parts', - 'car_rental', - 'car_repair', - 'car_sharing', - 'car_wash', - 'car', - 'carousel', - 'cemetery', - 'chalet', - 'charging_station', - 'childcare', - 'clinic', - 'clothes', - 'college', - 'computer', - 'convenience', - 'customs', - 'dentist', - 'district', - 'doctors', - 'dog_park', - 'drinking_water', - 'emergency_phone', - 'fashion', - 'firepit', - 'fishing', - 'florist', - 'forest', - 'fuel', - 'gambling', - 'garden_centre', - 'gift', - 'golf_course', - 'golf', - 'greengrocer', - 'grocery', - 'guest_house', - 'hairdresser', - 'hanami', - 'harbourmaster', - 'hifi', - 'hospital', - 'hostel', - 'hotel', - 'hunting_stand', - 'information', - 'jewelry', - 'karaoke_box', - 'karaoke', - 'landmark', - 'library', - 'life_ring', - 'lottery', - 'marina', - 'maze', - 'memorial', - 'military', - 'mobile_phone', - 'money_transfer', - 'motorcycle_parking', - 'motorcycle', - 'national_park', - 'naval_base', - 'newsagent', - 'optician', - 'park', - 'parking', - 'perfumery', - 'picnic_site', - 'picnic_table', - 'pitch', - 'playground', - 'post_box', - 'post_office', - 'ranger_station', - 'recycling', - 'roller_coaster', - 'sanitary_dump_station', - 'school', - 'scuba_diving', - 'shelter', - 'ship_chandler', - 'shower', - 'slipway', - 'snowmobile', - 'social_facility', - 'stadium', - 'stationery', - 'studio', - 'summer_toboggan', - 'supermarket', - 'swimming_area', - 'taxi', - 'telephone', - 'tobacco', - 'toilets', - 'townhall', - 'trail_riding_station', - 'travel_agency', - 'university', - 'viewpoint', - 'waste_basket', - 'waste_disposal', - 'water_point', - 'water_slide', - 'watering_place', - 'wayside_cross', - 'wilderness_hut', - ].includes(String(props['pmap:kind'])); + labelRules: labelRules(mapTheme).concat( + { + dataLayer: 'pois', + symbolizer: new GroupSymbolizer([ + new CircleSymbolizer({ + fill: '#0a165e', + stroke: '#f4f4f4', + }), + new OffsetTextSymbolizer({ + labelProps: ['name'], + fill: '#0a165e', + stroke: '#f4f4f4', + width: 1, + lineHeight: 0.875, + font: '400 16px', + offsetY: 4, + // offsetX: 6, + placements: [TextPlacements.S], + justify: Justify.Center, + }), + ]), + filter: (_, { props }) => + [ + 'attraction', + 'landmark', + 'memorial', + 'social_facility', + 'supermarket', + ].includes(String(props['pmap:kind'])), }, - }), + { + dataLayer: 'pois', + symbolizer: new CenteredTextSymbolizer({ + labelProps: ['name'], + fill: '#0a165e', + stroke: 'transparent', + width: 1, + lineHeight: 1, + font: '400 14px', + }), + filter: (z, { props }) => { + if (z < 18) return false; + return [ + 'aerodrome', + 'adult_gaming_centre', + 'airfield', + 'alpine_hut', + 'amusement_ride', + 'animal', + 'art', + 'artwork', + 'atm', + 'attraction', + 'atv', + 'baby_hatch', + 'bakery', + 'bbq', + 'beauty', + 'bed_and_breakfast', + 'bench', + 'bicycle_parking', + 'bicycle_rental', + 'bicycle_repair_station', + 'boat_storage', + 'bookmaker', + 'books', + 'bureau_de_change', + 'bus_stop', + 'butcher', + 'cafe', + 'camp_site', + 'car_parts', + 'car_rental', + 'car_repair', + 'car_sharing', + 'car_wash', + 'car', + 'carousel', + 'cemetery', + 'chalet', + 'charging_station', + 'childcare', + 'clinic', + 'clothes', + 'college', + 'computer', + 'convenience', + 'customs', + 'dentist', + 'district', + 'doctors', + 'dog_park', + 'drinking_water', + 'emergency_phone', + 'fashion', + 'firepit', + 'fishing', + 'florist', + 'forest', + 'fuel', + 'gambling', + 'garden_centre', + 'gift', + 'golf_course', + 'golf', + 'greengrocer', + 'grocery', + 'guest_house', + 'hairdresser', + 'hanami', + 'harbourmaster', + 'hifi', + 'hospital', + 'hostel', + 'hotel', + 'hunting_stand', + 'information', + 'jewelry', + 'karaoke_box', + 'karaoke', + 'landmark', + 'library', + 'life_ring', + 'lottery', + 'marina', + 'maze', + 'memorial', + 'military', + 'mobile_phone', + 'money_transfer', + 'motorcycle_parking', + 'motorcycle', + 'national_park', + 'naval_base', + 'newsagent', + 'optician', + 'park', + 'parking', + 'perfumery', + 'picnic_site', + 'picnic_table', + 'pitch', + 'playground', + 'post_box', + 'post_office', + 'ranger_station', + 'recycling', + 'roller_coaster', + 'sanitary_dump_station', + 'school', + 'scuba_diving', + 'shelter', + 'ship_chandler', + 'shower', + 'slipway', + 'snowmobile', + 'social_facility', + 'stadium', + 'stationery', + 'studio', + 'summer_toboggan', + 'supermarket', + 'swimming_area', + 'taxi', + 'telephone', + 'tobacco', + 'toilets', + 'townhall', + 'trail_riding_station', + 'travel_agency', + 'university', + 'viewpoint', + 'waste_basket', + 'waste_disposal', + 'water_point', + 'water_slide', + 'watering_place', + 'wayside_cross', + 'wilderness_hut', + ].includes(String(props['pmap:kind'])); + }, + }, + ), }); // @ts-expect-error -- this is what the docs recommend