def get_map_size(format): print_conf = Config.get_object_path('print', required=['basic_map_size', 'pdf_dpi', 'pdf_map_size_millimeters']) if format != 'pdf': return print_conf['basic_map_size'] else: pixel_size = print_conf['pdf_dpi'] / 25.4 map_size_mm = print_conf['pdf_map_size_millimeters'] return [pixel_size * map_size_mm[0], pixel_size * map_size_mm[1]]
def get_bbox(geometry): """ Return a bbox adapted for the map size specified in the print configuration and based on the geometry and a buffer (margin to add between the geometry and the border of the map). Args: geometry (list): The geometry (bbox) of the feature to center the map on. Returns: list: The bbox (meters) for the print. """ print_conf = Config.get_object_path( 'print', required=['basic_map_size', 'buffer']) print_buffer = print_conf['buffer'] map_size = print_conf['basic_map_size'] map_width = float(map_size[0]) map_height = float(map_size[1]) geom_bounds = geometry.bounds geom_width = float(geom_bounds[2] - geom_bounds[0]) geom_height = float(geom_bounds[3] - geom_bounds[1]) geom_ration = geom_width / geom_height map_ration = map_width / map_height # If the format of the map is naturally adapted to the format of the geometry is_format_adapted = geom_ration < map_ration if is_format_adapted: map_height_without_buffer = map_height - 2 * print_buffer # Calculate the new height of the geom with the buffer. geom_height_with_buffer = map_height / map_height_without_buffer * geom_height # Calculate the new geom width with the map ratio and the new geom height. geom_width_with_buffer = geom_height_with_buffer * map_ration else: map_width_without_buffer = map_width - 2 * print_buffer # Calculate the new width of the geom with the buffer. geom_width_with_buffer = map_width / map_width_without_buffer * geom_width # Calculate the new geom height with the map ratio and the new geom width. geom_height_with_buffer = geom_width_with_buffer * map_ration height_to_add = (geom_height_with_buffer - geom_height) / 2 width_to_add = (geom_width_with_buffer - geom_width) / 2 return [ geom_bounds[0] - width_to_add, geom_bounds[1] - height_to_add, geom_bounds[2] + width_to_add, geom_bounds[3] + height_to_add, ]
def get_bbox(geometry): """ Return a bbox adapted for the map size specified in the print configuration and based on the geometry and a buffer (margin to add between the geometry and the border of the map). Args: geometry (list): The geometry (bbox) of the feature to center the map on. Returns: list: The bbox (meters) for the print. """ print_conf = Config.get_object_path( 'print', required=['basic_map_size', 'buffer']) print_buffer = print_conf['buffer'] map_size = print_conf['basic_map_size'] map_width = float(map_size[0]) map_height = float(map_size[1]) if print_buffer * 2 >= min(map_width, map_height): error_msg_txt = 'Your print buffer ({}px)'.format(print_buffer) error_msg_txt += ' applied on each side of the feature exceed the smaller' error_msg_txt += ' side of your map {}px.'.format( min(map_width, map_height)) raise ConfigurationError(error_msg_txt) geom_bounds = geometry.bounds geom_width = float(geom_bounds[2] - geom_bounds[0]) geom_height = float(geom_bounds[3] - geom_bounds[1]) geom_ration = geom_width / geom_height map_ration = map_width / map_height # If the format of the map is naturally adapted to the format of the geometry is_format_adapted = geom_ration > map_ration if is_format_adapted: # Part (percent) of the margin compared to the map width. margin_in_percent = 2 * print_buffer / map_width # Size of the margin in geom units. geom_margin = geom_width * margin_in_percent # Geom width with the margins (right and left). adapted_geom_width = geom_width + (2 * geom_margin) # Adapted geom height to the map height adapted_geom_height = (adapted_geom_width / map_width) * map_height else: # Part (percent) of the margin compared to the map height. margin_in_percent = 2 * print_buffer / map_height # Size of the margin in geom units. geom_margin = geom_height * margin_in_percent # Geom height with the buffer (top and bottom). adapted_geom_height = geom_height + (2 * geom_margin) # Adapted geom width to the map width adapted_geom_width = (adapted_geom_height / map_height) * map_width height_to_add = (adapted_geom_height - geom_height) / 2 width_to_add = (adapted_geom_width - geom_width) / 2 return [ geom_bounds[0] - width_to_add, geom_bounds[1] - height_to_add, geom_bounds[2] + width_to_add, geom_bounds[3] + height_to_add, ]
def read(self, real_estate, municipality_logo, params): """ This method finally creates the extract. .. note:: If you subclass this class your implementation needs to offer this method in the same signature. Means the parameters must be the same and the return must be a :ref:`api-pyramid_oereb-lib-records-extract-extractrecord`. Otherwise the API like way the server works would be broken. Args: real_estate (pyramid_oereb.lib.records.real_estate.RealEstateRecord): The real estate for which the report should be generated municipality_logo (pyramid_oereb.lib.records.image.ImageRecord): The municipality logo. params (pyramid_oereb.views.webservice.Parameter): The parameters of the extract request. Returns: pyramid_oereb.lib.records.extract.ExtractRecord: The extract record containing all gathered data. """ assert isinstance(municipality_logo, ImageRecord) print_conf = Config.get_object_path('print', required=['buffer']) map_size = ViewServiceRecord.get_map_size(params.format) bbox = ViewServiceRecord.get_bbox(real_estate.limit, map_size, print_conf['buffer']) bbox = box(bbox[0], bbox[1], bbox[2], bbox[3]) datasource = list() for plr_source in self._plr_sources_: if not params.skip_topic(plr_source.info.get('code')): plr_source.read(real_estate, bbox) for ds in plr_source.datasource: if not params.skip_topic(ds.theme.code): datasource.append(ds) real_estate.public_law_restrictions.extend(plr_source.records) concerned_themes = list() not_concerned_themes = list() themes_without_data = list() for plr in real_estate.public_law_restrictions: # Filter topics due to topics parameter if not params.skip_topic(plr.theme.code): if isinstance(plr, PlrRecord): contained = False for theme in concerned_themes: if theme.code == plr.theme.code: contained = True if not contained: concerned_themes.append(plr.theme) elif isinstance(plr, EmptyPlrRecord): if plr.has_data: not_concerned_themes.append(plr.theme) else: themes_without_data.append(plr.theme) # Load base data form configuration resolver = DottedNameResolver() date_method_string = Config.get('extract').get('base_data').get( 'methods').get('date') date_method = resolver.resolve(date_method_string) av_update_date = date_method(real_estate) base_data = Config.get_base_data(av_update_date) av_provider_method_string = Config.get('extract').get('base_data').get( 'methods').get('provider') av_provider_method = resolver.resolve(av_provider_method_string) cadaster_state = datetime.datetime.now() embeddable = EmbeddableRecord(cadaster_state, self.plr_cadastre_authority, av_provider_method(real_estate), av_update_date, datasource) self.extract = ExtractRecord(real_estate, self.logo_plr_cadastre, self.federal_logo, self.cantonal_logo, municipality_logo, self.plr_cadastre_authority, base_data, embeddable, concerned_theme=concerned_themes, not_concerned_theme=not_concerned_themes, theme_without_data=themes_without_data) return self.extract