Last active
September 18, 2015 17:45
-
-
Save rmarianski/c1b80ee6240641c1c9ca to your computer and use it in GitHub Desktop.
db migration 20150918
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- functions.sql will get run first | |
-- point.sql and polygon.sql will get run in parallel | |
-- cleanup-point.sql will get run after the new code gets deployed | |
-- diffs will be turned off before applying updates, and then re-enabled | |
-- nothing should lock the tables for reading though | |
-------------------------------------------------------------------------------- | |
-- functions.sql | |
CREATE OR REPLACE FUNCTION mz_calculate_poi_level( | |
aerialway_val text, | |
aeroway_val text, | |
amenity_val text, | |
barrier_val text, | |
craft_val text, | |
highway_val text, | |
historic_val text, | |
leisure_val text, | |
lock_val text, | |
man_made_val text, | |
natural_val text, | |
office_val text, | |
power_val text, | |
railway_val text, | |
shop_val text, | |
tourism_val text, | |
waterway_val text, | |
way_area real | |
) | |
RETURNS SMALLINT AS $$ | |
DECLARE | |
zoom smallint; | |
BEGIN | |
zoom = | |
CASE WHEN natural_val IN ('peak', 'volcano') THEN 11 | |
WHEN railway_val IN ('station') THEN 12 | |
WHEN (aeroway_val IN ('aerodrome', 'airport') | |
OR aerialway_val IN ('station') | |
OR railway_val IN ('halt', 'tram_stop') | |
OR tourism_val IN ('alpine_hut', 'zoo')) THEN 13 | |
WHEN (natural_val IN ('spring') | |
OR railway_val IN ('level_crossing')) THEN 14 | |
WHEN (amenity_val IN ('hospital') | |
OR barrier_val IN ('gate') | |
OR craft_val IN ('sawmill') | |
OR highway_val IN ('gate', 'mini_roundabout') | |
OR lock_val IN ('yes') | |
OR man_made_val IN ('lighthouse', 'power_wind') | |
OR natural_val IN ('cave_entrance') | |
OR power_val IN ('generator') | |
OR waterway_val IN ('lock')) THEN 15 | |
WHEN (aeroway_val IN ('helipad') | |
OR amenity_val IN ('biergarten', 'bus_station', 'car_sharing', | |
'picnic_site', 'place_of_worship', | |
'prison', 'pub', 'recycling', 'shelter') | |
OR barrier_val IN ('block', 'bollard', 'lift_gate') | |
OR craft_val IN ('brewery', 'winery', 'sawmill') | |
OR highway_val IN ('ford') | |
OR historic_val IN ('archaeological_site') | |
OR man_made_val IN ('windmill') | |
OR natural_val IN ('tree') | |
OR shop_val IN ('department_store', 'supermarket') | |
OR tourism_val IN ('camp_site', 'caravan_site', 'information', 'viewpoint')) THEN 16 | |
WHEN (aeroway_val IN ('gate') | |
OR amenity_val IN ( | |
'atm', 'bank', 'bar', 'bicycle_rental', 'bicycle_parking', 'bus_stop', | |
'cafe', 'cinema', 'courthouse', 'drinking_water', 'embassy', 'emergency_phone', | |
'fast_food', 'fire_station', 'fuel', 'library', 'parking', 'pharmacy', | |
'police', 'post_box', 'post_office', 'restaurant', 'telephone', 'theatre', | |
'toilets', 'veterinary') | |
OR craft_val IN ('brewery', 'carpenter', 'confectionery', 'dressmaker', | |
'electrician', 'gardener', 'handicraft', 'hvac', 'metal_construction', | |
'painter', 'photographer', 'photographic_laboratory', 'plumber', | |
'pottery', 'sawmill', 'shoemaker', 'stonemason', 'tailor', 'winery') | |
OR highway_val IN ('bus_stop', 'traffic_signals') | |
OR historic_val IN ('memorial') | |
OR leisure_val IN ('playground', 'slipway') | |
OR man_made_val IN ('mast', 'water_tower') | |
OR office_val IN ('accountant', 'administrative', 'advertising_agency', | |
'architect', 'association', 'company', 'consulting', 'educational_institution', | |
'employment_agency', 'estate_agent', 'financial', 'foundation', 'government', | |
'insurance', 'it', 'lawyer', 'newspaper', 'ngo', 'notary', 'physician', | |
'political_party', 'religion', 'research', 'tax_advisor', 'telecommunication', | |
'therapist', 'travel_agent', 'yes') | |
OR shop_val IN ('bakery', 'bicycle', 'books', 'butcher', 'car', 'car_repair', | |
'clothes', 'computer', 'convenience', | |
'doityourself', 'dry_cleaning', 'fashion', 'florist', 'gift', | |
'greengrocer', 'hairdresser', 'jewelry', 'mobile_phone', | |
'optician', 'pet') | |
OR tourism_val IN ('bed_and_breakfast', 'chalet', 'guest_house', | |
'hostel', 'hotel', 'motel', 'museum') | |
OR railway_val IN ('subway_entrance')) THEN 17 | |
WHEN (amenity_val IN ('bench', 'waste_basket')) THEN 18 | |
ELSE NULL END; | |
RETURN (CASE | |
WHEN way_area > 1.0e7 THEN zoom - 4 | |
WHEN way_area > 1.0e6 THEN zoom - 3 | |
WHEN way_area > 1.0e5 THEN zoom - 2 | |
WHEN way_area > 1.0e4 THEN zoom - 1 | |
ELSE zoom END); | |
END; | |
$$ LANGUAGE plpgsql IMMUTABLE; | |
-- adds the prefix onto every key in an hstore value | |
CREATE OR REPLACE FUNCTION mz_hstore_add_prefix( | |
tags hstore, | |
prefix text) | |
RETURNS hstore AS $$ | |
DECLARE | |
new_tags hstore; | |
BEGIN | |
SELECT hstore(array_agg(prefix || key), array_agg(value)) | |
INTO STRICT new_tags | |
FROM each(tags); | |
RETURN new_tags; | |
END; | |
$$ LANGUAGE plpgsql IMMUTABLE; | |
-- OSM tags are often structured as a list separated by ':'s. | |
-- to preserve some kind of ordering information, we want to | |
-- insert an element in this "list" after the first element. | |
-- i.e: mz_insert_one_level('foo:bar', 'x') -> 'foo:x:bar'. | |
CREATE OR REPLACE FUNCTION mz_insert_one_level( | |
tag text, | |
str text) | |
RETURNS text AS $$ | |
DECLARE | |
arr text[] = string_to_array(tag, ':'); | |
fst text = arr[1]; | |
len int = array_upper(arr, 1); | |
rst text[] = arr[2:len]; | |
BEGIN | |
RETURN array_to_string(ARRAY[fst, str] || rst, ':'); | |
END; | |
$$ LANGUAGE plpgsql IMMUTABLE; | |
-- adds an infix value into every key in an hstore value after | |
-- the first element. so 'foo:bar=>bat' with infix 'x' becomes | |
-- 'foo:x:bar=>bat'. | |
CREATE OR REPLACE FUNCTION mz_hstore_add_infix( | |
tags hstore, | |
infix text) | |
RETURNS hstore AS $$ | |
DECLARE | |
new_tags hstore; | |
BEGIN | |
SELECT hstore(array_agg(mz_insert_one_level(key, infix)), array_agg(value)) | |
INTO STRICT new_tags | |
FROM each(tags); | |
RETURN new_tags; | |
END; | |
$$ LANGUAGE plpgsql IMMUTABLE; | |
-------------------------------------------------------------------------------- | |
-- point.sql | |
ALTER TABLE planet_osm_point ADD COLUMN mz_poi_min_zoom SMALLINT; | |
UPDATE planet_osm_point SET | |
mz_poi_min_zoom = mz_calculate_poi_level("aerialway", "aeroway", "amenity", "barrier", "craft", "highway", "historic", "leisure", "lock", "man_made", "natural", "office", "power", "railway", "shop", "tourism", "waterway", 0::real) | |
WHERE coalesce("aerialway", "aeroway", "amenity", "barrier", "craft", "highway", "historic", "leisure", "lock", "man_made", "natural", "office", "power", "railway", "shop", "tourism", "waterway") IS NOT NULL; | |
CREATE OR REPLACE FUNCTION mz_trigger_function_point() | |
RETURNS TRIGGER AS $$ | |
BEGIN | |
NEW.mz_poi_min_zoom := mz_calculate_poi_level(NEW."aerialway", NEW."aeroway", NEW."amenity", NEW."barrier", NEW."craft", NEW."highway", NEW."historic", NEW."leisure", NEW."lock", NEW."man_made", NEW."natural", NEW."office", NEW."power", NEW."railway", NEW."shop", NEW."tourism", NEW."waterway", 0::real); | |
RETURN NEW; | |
END; | |
$$ LANGUAGE plpgsql VOLATILE; | |
CREATE TRIGGER mz_trigger_point BEFORE INSERT OR UPDATE ON planet_osm_point FOR EACH ROW EXECUTE PROCEDURE mz_trigger_function_point(); | |
-------------------------------------------------------------------------------- | |
-- polygon.sql | |
DROP TRIGGER mz_trigger_landuse ON planet_osm_polygon; | |
DROP FUNCTION mz_trigger_function_landuse(); | |
ALTER TABLE planet_osm_polygon ADD COLUMN mz_poi_min_zoom SMALLINT; | |
UPDATE planet_osm_polygon SET | |
mz_poi_min_zoom = mz_calculate_poi_level("aerialway", "aeroway", "amenity", "barrier", "craft", "highway", "historic", "leisure", "lock", "man_made", "natural", "office", "power", "railway", "shop", "tourism", "waterway", way_area) | |
WHERE coalesce("aerialway", "aeroway", "amenity", "barrier", "craft", "highway", "historic", "leisure", "lock", "man_made", "natural", "office", "power", "railway", "shop", "tourism", "waterway") IS NOT NULL; | |
CREATE OR REPLACE FUNCTION mz_trigger_function_polygon() | |
RETURNS TRIGGER AS $$ | |
DECLARE | |
mz_is_landuse BOOLEAN = mz_calculate_is_landuse(NEW."landuse", NEW."leisure", NEW."natural", NEW."highway", NEW."amenity", NEW."aeroway", NEW."tourism", NEW."man_made", NEW."power"); | |
mz_poi_min_zoom SMALLINT = mz_calculate_poi_level(NEW."aerialway", NEW."aeroway", NEW."amenity", NEW."barrier", NEW."craft", NEW."highway", NEW."historic", NEW."leisure", NEW."lock", NEW."man_made", NEW."natural", NEW."office", NEW."power", NEW."railway", NEW."shop", NEW."tourism", NEW."waterway", NEW.way_area); | |
BEGIN | |
IF mz_is_landuse THEN | |
NEW.mz_is_landuse := TRUE; | |
ELSE | |
NEW.mz_is_landuse := NULL; | |
END IF; | |
NEW.mz_poi_min_zoom := mz_poi_min_zoom; | |
IF mz_is_landuse OR mz_poi_min_zoom IS NOT NULL THEN | |
NEW.mz_centroid := ST_Centroid(NEW.way); | |
ELSE | |
NEW.mz_centroid := NULL; | |
END IF; | |
RETURN NEW; | |
END; | |
$$ LANGUAGE plpgsql VOLATILE; | |
CREATE TRIGGER mz_trigger_polygon BEFORE INSERT OR UPDATE ON planet_osm_polygon FOR EACH ROW EXECUTE PROCEDURE mz_trigger_function_polygon(); | |
-------------------------------------------------------------------------------- | |
-- cleanup-point.sql - to be run after new code gets deployed | |
DROP INDEX planet_osm_point_level_index; | |
DROP FUNCTION mz_calculate_poi_level(text, text, text, text, text, text, text, text, text,text, text, text, text, text, text, text, text); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment