diff --git a/config.example.py b/config.example.py index fce6bd810..71321cd1e 100644 --- a/config.example.py +++ b/config.example.py @@ -178,6 +178,8 @@ # allow displaying the live location of workers on the map MAP_WORKERS = True +# Highligh EX Raid Gyms on map (default False, uncomment to enable) +#MAP_SHOW_EX_GYMS = True # filter these Pokemon from the map to reduce traffic and browser load #MAP_FILTER_IDS = [161, 165, 16, 19, 167] diff --git a/monocle/sanitized.py b/monocle/sanitized.py index b6bfbc4aa..ed3544847 100644 --- a/monocle/sanitized.py +++ b/monocle/sanitized.py @@ -74,6 +74,7 @@ 'MAP_FILTER_IDS': sequence, 'MAP_PROVIDER_ATTRIBUTION': str, 'MAP_PROVIDER_URL': str, + 'MAP_SHOW_EX_GYMS': bool, 'MAP_START': sequence, 'MAP_WORKERS': bool, 'MAX_CAPTCHAS': int, @@ -190,6 +191,7 @@ 'MAP_FILTER_IDS': None, 'MAP_PROVIDER_URL': '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 'MAP_PROVIDER_ATTRIBUTION': '© OpenStreetMap contributors', + 'MAP_SHOW_EX_GYMS': False, 'MAP_WORKERS': True, 'MAX_CAPTCHAS': 0, 'MAX_RETRIES': 3, diff --git a/monocle/static/css/main.css b/monocle/static/css/main.css index 7ef71be4e..db9aca9ec 100644 --- a/monocle/static/css/main.css +++ b/monocle/static/css/main.css @@ -57,6 +57,10 @@ box-shadow: 0 0 3px rgba(0, 0, 0, 0.5); } +.ex-raid-gym { + background: #0f0; +} + .leaflet-control-layers-toggle { background-image: url('../img/layers.png'); } @@ -215,4 +219,4 @@ } .instinct { background: #fe9c0a; -} \ No newline at end of file +} diff --git a/monocle/static/js/main.js b/monocle/static/js/main.js index 05dd02b35..c861f128a 100644 --- a/monocle/static/js/main.js +++ b/monocle/static/js/main.js @@ -210,6 +210,9 @@ function PokemonMarker (raw) { function FortMarker (raw) { var icon = new FortIcon({iconUrl: '/static/monocle-icons/forts/' + raw.team + '.png'}); + if (raw.ex) { + icon.options.className += " ex-raid-gym" + } var marker = L.marker([raw.lat, raw.lon], {icon: icon, opacity: 1}); marker.raw = raw; markers[raw.id] = marker; @@ -281,9 +284,9 @@ function RaidMarker (raw) { }, 2500); var userPreference = getPreference('raids-'+raw.level); - if (userPreference === 'show'){ + if (userPreference === 'show' || (userPreference === 'showex' && raw.ex)){ marker.overlay = 'Raids'; - }else if (userPreference === 'hide'){ + }else{ marker.overlay = 'Hidden'; } @@ -652,7 +655,7 @@ function moveToLayer(id, layer, type){ var m = markers[k]; if ((k.indexOf("raid-") > -1) && (m !== undefined) && (m.raw.level === id)){ m.removeFrom(overlays[m.overlay]); - if (layer === 'show'){ + if (layer === 'show' || (layer === 'showex' && m.raw.ex)){ m.overlay = "Raids"; m.addTo(overlays.Raids); }else{ @@ -688,6 +691,7 @@ function populateSettingsPanels(){ 'Level ' + i + ' (' + _raids_labels[i-1] + ')' + '
' + '' + + '' + '' + '
' + ''; @@ -701,7 +705,7 @@ function setSettingsDefaults(){ _defaultSettings['filter-'+i] = (_defaultSettings['TRASH_IDS'].indexOf(i) > -1) ? "trash" : "pokemon"; }; for (var i = 1; i <= _raids_count; i++){ - _defaultSettings['raids-'+i] = (_defaultSettings['RAIDS_FILTER'].indexOf(i) > -1) ? "show" : "hide"; + _defaultSettings['raids-'+i] = (_defaultSettings['RAIDS_FILTER'].indexOf(i) > -1) ? "show" : "showex"; }; $("#settings div.btn-group").each(function(){ diff --git a/monocle/web_utils.py b/monocle/web_utils.py index 6e69f2404..e436104c1 100644 --- a/monocle/web_utils.py +++ b/monocle/web_utils.py @@ -125,11 +125,13 @@ def get_pokemarkers(after_id=0): return tuple(map(sighting_to_marker, pokemons)) -def get_raid_markers(names=POKEMON, moves=MOVES): +def get_raid_markers(names=POKEMON, moves=MOVES, show_ex=conf.MAP_SHOW_EX_GYMS): with session_scope() as session: markers = [] raids = session.query(Raid) \ .filter(Raid.time_end > time()) + if show_ex: + forts = get_forts(session) for raid in raids: fort = session.query(Fort) \ .filter(Fort.id == raid.fort_id) \ @@ -140,6 +142,7 @@ def get_raid_markers(names=POKEMON, moves=MOVES): .first() markers.append({ 'id': 'raid-' + str(raid.id), + 'ex': show_ex and raid.fort_id in get_ex_raid_gyms(forts), 'level': raid.level, 'team': fortsighting.team, 'pokemon_id': raid.pokemon_id, @@ -180,11 +183,12 @@ def get_weather(): return markers -def get_gym_markers(names=POKEMON): +def get_gym_markers(names=POKEMON, show_ex=conf.MAP_SHOW_EX_GYMS): with session_scope() as session: forts = get_forts(session) return [{ 'id': 'fort-' + str(fort['fort_id']), + 'ex': show_ex and fort['fort_id'] in get_ex_raid_gyms(forts), 'sighting_id': fort['id'], 'prestige': fort['prestige'], 'pokemon_id': fort['guard_pokemon_id'], @@ -269,6 +273,42 @@ def get_all_parks(): return parks +def get_ex_raid_gyms(forts=None): + gyms = [] + with session_scope() as session: + if not forts: + forts = get_forts(session) + try: + pickle = load_pickle('ex_raid_gyms', raise_exception=True) + gyms = pickle['gyms'] + max_id = pickle.get('max_id', 0) + for g in forts: + if g['fort_id'] > max_id: + raise KeyError("Cache outdated") + except (FileNotFoundError, TypeError, KeyError): + parks = get_all_parks() + max_id = 0 + for g in forts: + if g['fort_id'] > max_id: + max_id = g['fort_id'] + gym_point = Point(g['lat'], g['lon']) + cell = Polygon(get_s2_cell_as_polygon(g['lat'], g['lon'], 20)) # s2 lvl 20 + for p in parks: + coords = p['coords'] + # osm polygon can be a line + if len(coords) == 2: + shape = LineString(coords) + if shape.within(cell.centroid): + gyms.append(g['fort_id']) + break + if len(coords) > 2: + shape = Polygon(coords) + if shape.contains(cell.centroid): + gyms.append(g['fort_id']) + break + dump_pickle('ex_raid_gyms', {"max_id": max_id, "gyms": gyms}) + return gyms + def get_s2_cells(n=north, w=west, s=south, e=east, level=12): region_covered = s2sphere.LatLngRect.from_point_pair( s2sphere.LatLng.from_degrees(n, w), diff --git a/raidex.py b/raidex.py index c007e3197..7128229f2 100644 --- a/raidex.py +++ b/raidex.py @@ -38,22 +38,9 @@ def fullmap(map_html=render_map()): def gym_data(): gyms = [] parks = get_all_parks() - for g in get_gym_markers(): - gym_point = Point(g['lat'], g['lon']) - cell = Polygon(get_s2_cell_as_polygon(g['lat'], g['lon'], 20)) # s2 lvl 20 - for p in parks: - coords = p['coords'] - # osm polygon can be a line - if len(coords) == 2: - shape = LineString(coords) - if shape.within(cell.centroid): - gyms.append(g) - break - if len(coords) > 2: - shape = Polygon(coords) - if shape.contains(cell.centroid): - gyms.append(g) - break + for g in get_gym_markers(show_ex=True): + if g['ex']: + gyms.append(g) return jsonify(gyms) @app.route('/parks_cells')