def test_compress_territory(): example_territory = Territory(12, representations=[MapistoShape(test_path, 0)], bounding_box=BoundingBox(0, 0, 100, 100), state_id=14, validity_start=datetime.now(), validity_end=datetime.now(), color='#FF0000', name="Algeria") compressed = compress_territory(example_territory) assert isinstance(compressed, Territory) # 0 is raw precision assert compressed.representations[0].precision_in_km == 0 for i, rep in enumerate(compressed.representations): assert isinstance(rep, MapistoShape) if i > 0: previous = compressed.representations[i - 1] # Assumes precision_levels is sorted asc # representations are sorted by precision asc assert rep.precision_in_km > previous.precision_in_km # Precision asc means size desc (as more precise = bigger definition) assert previous.precision_in_km == 0 or len(rep.d_path) <= len( previous.d_path) compressed.representations = [compressed.representations[0]] assert compressed.equals(example_territory)
def get_within_bbox_at_time(cursor, bbox, date, precision_level): assert isinstance(bbox, BoundingBox) assert isinstance(date, datetime) cursor.execute( ''' SELECT territories.territory_id, state_id, min_x, min_y, max_x-min_x, max_y-min_y, validity_start, validity_end, color, name, d_path FROM territories INNER JOIN territories_shapes ON territories.territory_id=territories_shapes.territory_id WHERE territories.validity_start <= %s AND territories.validity_end > %s AND precision_in_km=%s AND NOT( %s < territories.min_x OR territories.max_x < %s OR %s < territories.min_y OR territories.max_y < %s ) ''', (date, date, precision_level, bbox.max_x, bbox.x, bbox.max_y, bbox.y)) return [ Territory(territory_id, [MapistoShape(d_path, precision_level)], state_id, BoundingBox(x, y, width, height), validity_start, validity_end, color, name) for (territory_id, state_id, x, y, width, height, validity_start, validity_end, color, name, d_path) in cursor.fetchall() ]
def compress_territory(territory): assert isinstance(territory, Territory) return Territory(territory.territory_id, _get_compressed_shapes(territory.representations[0]), territory.state_id, territory.bounding_box, territory.validity_start, territory.validity_end, territory.color, territory.name)
def to_territory(svg_path): return Territory.from_dict({ 'd_path' : svg_path, 'state_id' : 12, 'color' : '#FF0000', 'validity_start' : '1918-01-01T00:00:00Z', 'validity_end' : '1919-01-01T00:00:00Z', 'name' : 'Algeria' } )
def get_example_territory(): territory = Territory.from_dict({ 'd_path': "M 0 1 L 0 0 L 1 0 L 1 1 Z", 'state_id': 12, 'color': '#FF0000', 'validity_start': '1918-01-01T00:00:00Z', 'validity_end': '1919-01-01T00:00:00Z', 'name': 'Algeria'}) offset=datetime.now().timestamp() x = offset + randint(1, 1e6) y=offset + randint(1, 1e6) translate_terr(territory,x, y) return territory
def _assign_to_state(cursor, territory, target_state_id): assert isinstance(territory, Territory) assert isinstance(target_state_id, int) created_territories_ids = [] target_state = StateCRUD.get(cursor, target_state_id) if target_state.validity_end <= territory.validity_start or target_state.validity_start >= territory.validity_end: raise BadRequest( f'The territory goes from {territory.validity_start} to {territory.validity_end} and has no time in common with state from {target_state.validity_start} to {target_state.validity_end}' ) if target_state.validity_end < territory.validity_end: to_add_at_end = Territory(None, territory.representations, territory.state_id, territory.bounding_box, target_state.validity_end, territory.validity_end, territory.color, territory.name) created_territories_ids.append( TerritoryCRUD.add(cursor, to_add_at_end)) territory.validity_end = target_state.validity_end TerritoryCRUD.edit(cursor, territory, change_end=True) if target_state.validity_start > territory.validity_start: to_add_at_start = Territory(None, territory.representations, territory.state_id, territory.bounding_box, territory.validity_start, target_state.validity_start, territory.color, territory.name) created_territories_ids.append( TerritoryCRUD.add(cursor, to_add_at_start)) territory.validity_start = target_state.validity_start TerritoryCRUD.edit(cursor, territory, change_start=True) new_color = TerritoryTag._get_color_for_territory( territory, StateCRUD.get(cursor, territory.state_id), target_state) if new_color != territory.color: territory.color = new_color TerritoryCRUD.edit(cursor, territory, change_color=True) territory.state_id = target_state.state_id TerritoryCRUD.edit(cursor, territory, change_state_id=True) return created_territories_ids
def get_by_state(cursor, state_id): assert isinstance(state_id, int) cursor.execute( ''' SELECT territory_id, min_x, min_y, max_x-min_x, max_y-min_y, validity_start, validity_end, color, name FROM territories WHERE state_id=%s ''', (state_id, )) res = [] for row in cursor.fetchall(): (territory_id, x, y, width, height, validity_start, validity_end, color, name) = row res.append( Territory(territory_id, [], state_id, BoundingBox(x, y, width, height), validity_start, validity_end, color, name)) return res
def get(cursor, id): cursor.execute( ''' SELECT territories.territory_id, state_id, min_x, min_y, max_x-min_x, max_y-min_y, validity_start, validity_end, color, name, d_path, precision_in_km FROM territories INNER JOIN territories_shapes ON territories.territory_id=territories_shapes.territory_id WHERE territories.territory_id=%s ORDER BY precision_in_km ''', (id, )) rows = cursor.fetchall() if not len(rows): raise NotFound(f'Territory not found : {id}') (territory_id, state_id, x, y, width, height, validity_start, validity_end, color, name, _, _) = rows[0] bounding_box = BoundingBox(x, y, width, height) representations = [MapistoShape(row[10], row[11]) for row in rows] return Territory(territory_id, representations, state_id, bounding_box, validity_start, validity_end, color, name)
def test_edit_territory(): corsica = Territory.from_dict({ # bounding box -5 , 10, 16, 16 'd_path': "M 0.1 10 L 10.12 20 L 0 25.7 L -2 17 L -3 16 L -5 10 Z", 'state_id': 12, 'validity_start': '1916-01-01T00:00:00Z', 'validity_end': '1919-01-01T00:00:00Z', 'name': 'Corsica' }) with get_db_with_states_cursor(france_1912_2018) as cursor: france_id = StateCRUD.get_by_name( cursor, 'France', france_1912_2018.validity_start, france_1912_2018.validity_end)[0].state_id corsica.state_id = france_id corsica_id = TerritoryCRUD.add(cursor, corsica) corsica.territory_id = corsica_id corsica.color = '#FFFFFF' TerritoryCRUD.edit(cursor, corsica) retrieved = TerritoryCRUD.get(cursor, corsica_id) assert retrieved.color is None TerritoryCRUD.edit(cursor, corsica, change_color=True) retrieved = TerritoryCRUD.get(cursor, corsica_id) assert retrieved.color == corsica.color
def put_territory(): return { "modified_territory": TerritoryTag.put(Territory.from_dict(request.json)) }
def post_territory(): return { "added_territory": TerritoryTag.post(Territory.from_dict(request.json)) }
from resources.Territory import Territory from .Territory_CRUD import TerritoryCRUD from resources.State import State from .State_CRUD import StateCRUD import contextlib from dateutil import parser from .db import get_cursor import pytest from werkzeug.exceptions import NotFound from resources.BoundingBox import BoundingBox algeria = Territory.from_dict({ # bounding box -5 , 0, 16, 16 'd_path': "M 0.1 0 L 10.12 10 L 0 15.7 L -2 7 L -3 6 L -5 0 Z", 'state_id': 12, 'validity_start': '1918-01-01T00:00:00Z', 'validity_end': '1919-01-01T00:00:00Z', 'name': 'Algeria' }) corsica = Territory.from_dict({ # bounding box -5 , 10, 16, 16 'd_path': "M 0.1 10 L 10.12 20 L 0 25.7 L -2 17 L -3 16 L -5 10 Z", 'state_id': 12, 'validity_start': '1916-01-01T00:00:00Z', 'validity_end': '1919-01-01T00:00:00Z', 'name': 'Corsica' }) def year_to_date(y): return parser.parse(f'{y}-01-01T00:00:00Z')