예제 #1
0
    def __merge_with_cursor(cursor, to_merge_id, sovereign_state_id):
        assert isinstance(to_merge_id, int)
        assert isinstance(sovereign_state_id, int)
        to_merge = StateCRUD.get(cursor, to_merge_id)
        sovereign = StateCRUD.get(cursor, sovereign_state_id)
        if to_merge.validity_start < sovereign.validity_start or to_merge.validity_end > sovereign.validity_end:
            raise MergeStateConflictException(
                f'The state to merge period {(to_merge.validity_start, to_merge.validity_end)} overflows the period of the sovereign state {(sovereign.validity_start, sovereign.validity_end)}',
                [
                    t.territory_id
                    for t in TerritoryCRUD.get_by_state(cursor, to_merge_id)
                ])
        territories_to_change = TerritoryCRUD.get_by_state(cursor, to_merge_id)
        for territory in territories_to_change:

            # Color integrity check
            its_color = territory.color
            if not its_color:
                candidate_colors = [
                    r.color
                    for r in to_merge.representations if r.period_intersects(
                        territory.validity_start, territory.validity_end)
                ]
                # All representation matching with the territory have similar color => territory color can be determined (else too complex nothing is done)
                if all(
                        colours_roughly_equal(candidate_colors[0], c)
                        for c in candidate_colors[1:]):
                    its_color = candidate_colors[0]
            if its_color:
                sovereign_color = [
                    r.color
                    for r in sovereign.representations if r.period_intersects(
                        territory.validity_start, territory.validity_end)
                ]
                if all(
                        colours_roughly_equal(c, its_color)
                        for c in sovereign_color):
                    territory.color = None
                # Destination color is different => set the territory color to preserve it
                else:
                    territory.color = its_color
                TerritoryCRUD.edit(cursor, territory, change_color=True)

            territory.state_id = sovereign_state_id
            TerritoryCRUD.edit(cursor, territory, change_state_id=True)
        StateCRUD.delete(cursor, to_merge_id)
        return sovereign_state_id
예제 #2
0
 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
예제 #3
0
 def delete(territory_id):
     with get_cursor() as cursor:
         territory = TerritoryCRUD.get(cursor, territory_id)
         state = StateCRUD.get(cursor, territory.state_id)
         if len(state.representations
                ) == 1 and not state.representations[0].name:
             its_territories = TerritoryCRUD.get_by_state(
                 cursor, territory.state_id)
             if len(its_territories) == 1:
                 StateCRUD.delete(cursor, state.state_id)
                 return {
                     "deleted_state": state.state_id,
                     "deleted_territory": territory_id
                 }
         TerritoryCRUD.delete(cursor, territory_id)
         return {"deleted_state": None, "deleted_territory": territory_id}
예제 #4
0
 def post(territory):
     assert isinstance(territory, Territory)
     with get_cursor() as cursor:
         state = StateCRUD.get(cursor, territory.state_id)
         if territory.validity_start < state.validity_start or territory.validity_end > state.validity_end:
             raise Conflict(
                 f"Cannot add territory ({territory.validity_start} , {territory.validity_end}) to state ({state.validity_start}, {state.validity_end}) : period overflows"
             )
         potentially_intersecting = TerritoryCRUD.get_within_bbox_in_period(
             cursor, territory.bounding_box, territory.validity_start,
             territory.validity_end, 0)
         t_conflict_ids = [
             other.territory_id for other in potentially_intersecting
             if territories_conflict(territory, other)
         ]
         if len(t_conflict_ids):
             raise Conflict(
                 f"Cannot add the territory : it conflicts with territories {t_conflict_ids}"
             )
         compressed_territory = compress_territory(territory)
         return TerritoryCRUD.add(cursor, compressed_territory)
예제 #5
0
 def get(state_id):
     assert isinstance(state_id, int)
     with get_cursor() as cursor:
         return StateCRUD.get(cursor, state_id)