Пример #1
0
    def _sort_sub_themes(self, restrictions):
        # split restrictions by theme codes
        split_by_theme_code = self._split_restrictions_by_theme_code(
            restrictions)

        # sort sub themes of the same theme
        for theme_code in split_by_theme_code:
            sub_themes = []
            non_sub_themes = []
            for restriction in split_by_theme_code[theme_code]:
                if restriction.get('Split_SubTheme', False):
                    sub_themes.append(restriction)
                else:
                    non_sub_themes.append(restriction)
            # only sort if there are multiple sub themes
            if len(sub_themes) > 1:
                sorter, params = self._get_sorter(theme_code)
                sub_themes = sorter.sort(sub_themes, params)
            split_by_theme_code[theme_code] = non_sub_themes + sub_themes

        # sort + flatten the split themes again
        sorted_restrictions = []
        for theme in Config.get_themes():
            if theme.code in split_by_theme_code:
                sorted_restrictions += split_by_theme_code[theme.code]

        return sorted_restrictions
Пример #2
0
    def get_capabilities(self):
        """
        Returns the capabilities of this service.

        Returns:
            pyramid.response.Response: The `capabilities` response.
        """
        themes = list()
        for theme in Config.get_themes():
            text = list()
            for lang in theme.text:
                text.append({
                    'Language': lang,
                    'Text': theme.text[lang]
                })
            themes.append({
                'Code': theme.code,
                'Text': text
            })
        capabilities = {
            u'GetCapabilitiesResponse': {
                u'topic': themes,
                u'municipality': [record.fosnr for record in self._municipality_reader.read()],
                u'flavour': Config.get_flavour(),
                u'language': Config.get_language(),
                u'crs': Config.get_crs()
            }
        }
        renderer_name = 'json' if self._is_json() else 'pyramid_oereb_capabilities_xml'
        response = render_to_response(renderer_name, capabilities, request=self._request)
        if self._is_json():
            response.content_type = 'application/json; charset=UTF-8'
        return response
Пример #3
0
    def get_capabilities(self):
        """
        Returns the capabilities of this service.

        Returns:
            pyramid.response.Response: The `capabilities` response.
        """

        params = Parameter('json' if self._is_json() else 'xml')

        supported_languages = Config.get_language()
        themes = list()
        for theme in Config.get_themes():
            text = list()
            for lang in theme.text:
                if lang in supported_languages:
                    text.append({'Language': lang, 'Text': theme.text[lang]})
            themes.append({'Code': theme.code, 'Text': text})
        capabilities = {
            u'GetCapabilitiesResponse': {
                u'topic':
                themes,
                u'municipality': [
                    record.fosnr
                    for record in self._municipality_reader.read(params)
                ],
                u'flavour':
                Config.get_flavour(),
                u'language':
                supported_languages,
                u'crs': [Config.get_crs()]
            }
        }

        # Try - catch for backward compatibility with old specification.
        try:
            output_format = self.__validate_format_param__(['xml', 'json'])
        except HTTPBadRequest:
            output_format = None
            log.warning(
                'Deprecated way to specify the format. Use "/capabilities/{format}" instead'
            )
        renderer_name = 'json' if output_format == 'json' or self._is_json(
        ) else 'pyramid_oereb_capabilities_xml'  # noqa: E501
        response = render_to_response(renderer_name,
                                      capabilities,
                                      request=self._request)
        if self._is_json():
            response.content_type = 'application/json; charset=UTF-8'
        response.extras = OerebStats(service='GetCapabilities',
                                     output_format=output_format)
        return response
Пример #4
0
    def get_capabilities(self):
        """
        Returns the capabilities of this service.

        Returns:
            pyramid.response.Response: The `capabilities` response.
        """

        output_format = self.__validate_format_param__(self._DEFAULT_FORMATS)
        params = Parameter(output_format)

        supported_languages = Config.get_language()
        themes = list()
        for theme in Config.get_themes():
            text = list()
            for lang in theme.title:
                if lang in supported_languages:
                    text.append({'Language': lang, 'Text': theme.title[lang]})
            themes.append({'Code': theme.code, 'Text': text})
        processor = create_processor()
        capabilities = {
            u'GetCapabilitiesResponse': {
                u'topic':
                themes,
                u'municipality': [
                    record.fosnr
                    for record in processor.municipality_reader.read(params)
                ],
                u'flavour':
                Config.get_flavour(),
                u'language':
                supported_languages,
                u'crs': [Config.get_crs()]
            }
        }

        renderer_name = 'json' if output_format == 'json' else 'pyramid_oereb_capabilities_xml'  # noqa: E501
        response = render_to_response(renderer_name,
                                      capabilities,
                                      request=self._request)
        if output_format == 'json':
            response.content_type = 'application/json; charset=UTF-8'
        # response.extras = OerebStats(service='GetCapabilities', output_format=output_format)
        return response
Пример #5
0
    def convert_to_printable_extract(self, extract_dict, feature_geometry,
                                     pdf_to_join):
        """
        Converts an oereb extract into a form suitable for printing by mapfish print.

        Args:
            extract_dict: the oereb extract, will get converted by this function into a form
                            convenient for mapfish-print
            feature_geometry: the geometry for this extract, will get added to the extract information
            pdf_to_join: a set of additional information for the pdf. Will get filled by this function.
                         Used in the full extract only
        """

        log.debug(
            "Starting transformation, extract_dict is {}".format(extract_dict))
        log.debug("Parameter feature_geometry is {}".format(feature_geometry))

        creation_date = datetime.strptime(extract_dict['CreationDate'],
                                          '%Y-%m-%dT%H:%M:%S')
        extract_dict['Footer'] = '   '.join([
            creation_date.strftime('%d.%m.%Y'),
            creation_date.strftime('%H:%M:%S'),
            extract_dict['ExtractIdentifier']
        ])
        extract_dict['CreationDate'] = creation_date.strftime('%d.%m.%Y')

        for attr_name in [
                'NotConcernedTheme', 'ThemeWithoutData', 'ConcernedTheme'
        ]:
            for theme in extract_dict[attr_name]:
                self._localised_text(theme, 'Text')
        self._flatten_object(extract_dict, 'PLRCadastreAuthority')
        self._flatten_object(extract_dict, 'RealEstate')
        if 'Image' in extract_dict.get('RealEstate_Highlight', {}):
            del extract_dict['RealEstate_Highlight']['Image']

        main_page_url, main_page_params = \
            parse_url(extract_dict['RealEstate_PlanForLandRegisterMainPage']['ReferenceWMS'])
        base_url = urlparse.urlunsplit(
            (main_page_url.scheme, main_page_url.netloc, main_page_url.path,
             None, None))
        wms_url_params = self.get_wms_url_params()

        main_page_basemap = {
            'type':
            'wms',
            'styles':
            'default',
            'opacity':
            extract_dict['RealEstate_PlanForLandRegisterMainPage'].get(
                'layerOpacity', 0.6),
            'baseURL':
            base_url,
            'layers':
            main_page_params['LAYERS'][0].split(','),
            'imageFormat':
            'image/png',
            'customParams':
            wms_url_params,
        }
        extract_dict['baseLayers'] = {'layers': [main_page_basemap]}
        url, params = parse_url(
            extract_dict['RealEstate_PlanForLandRegister']['ReferenceWMS'])
        basemap = {
            'type':
            'wms',
            'styles':
            'default',
            'opacity':
            extract_dict['RealEstate_PlanForLandRegister'].get(
                'layerOpacity', 0.6),
            'baseURL':
            urlparse.urlunsplit(
                (url.scheme, url.netloc, url.path, None, None)),
            'layers':
            params['LAYERS'][0].split(','),
            'imageFormat':
            'image/png',
            'customParams':
            wms_url_params,
        }
        del extract_dict['RealEstate_PlanForLandRegister']  # /definitions/Map

        self._multilingual_m_text(extract_dict, 'GeneralInformation')
        self._multilingual_m_text(extract_dict, 'BaseData')
        self._multilingual_m_text(extract_dict, 'Certification')
        self._multilingual_m_text(extract_dict, 'CertificationAtWeb')

        for item in extract_dict.get('Glossary', []):
            self._multilingual_text(item, 'Title')
            self._multilingual_text(item, 'Content')
        self._multilingual_text(extract_dict, 'PLRCadastreAuthority_Name')

        for restriction_on_landownership in extract_dict.get(
                'RealEstate_RestrictionOnLandownership', []):
            self._flatten_object(restriction_on_landownership, 'Lawstatus')
            self._flatten_object(restriction_on_landownership, 'Theme')
            self._flatten_array_object(restriction_on_landownership,
                                       'Geometry', 'ResponsibleOffice')
            self._localised_text(restriction_on_landownership, 'Theme_Text')
            self._localised_text(restriction_on_landownership,
                                 'Lawstatus_Text')
            self._multilingual_m_text(restriction_on_landownership,
                                      'Information')

            self._multilingual_text(
                restriction_on_landownership['ResponsibleOffice'], 'Name')
            restriction_on_landownership['ResponsibleOffice'] = \
                [restriction_on_landownership['ResponsibleOffice']]

            url, params = parse_url(
                restriction_on_landownership['Map']['ReferenceWMS'])

            restriction_on_landownership['baseLayers'] = {
                'layers': [{
                    'type':
                    params.pop('SERVICE', ['wms'])[0].lower(),
                    'opacity':
                    restriction_on_landownership['Map'].get(
                        'layerOpacity', 0.6),
                    'styles':
                    params.pop('STYLES', ['default'])[0],
                    'baseURL':
                    urlparse.urlunsplit(
                        (url.scheme, url.netloc, url.path, None, None)),
                    'layers':
                    params.pop('LAYERS', '')[0].split(','),
                    'imageFormat':
                    params.pop('FORMAT', ['image/png'])[0],
                    'customParams':
                    self.get_custom_wms_params(params),
                }, basemap]
            }

            restriction_on_landownership[
                'legend'] = restriction_on_landownership['Map'].get(
                    'LegendAtWeb', '')

            # Legend of other visible restriction objects in the topic map
            restriction_on_landownership[
                'OtherLegend'] = restriction_on_landownership['Map'].get(
                    'OtherLegend', [])
            for legend_item in restriction_on_landownership['OtherLegend']:
                self._multilingual_text(legend_item, 'LegendText')

            for legend_entry in restriction_on_landownership['OtherLegend']:
                for element in list(legend_entry.keys()):
                    if element not in ['LegendText', 'SymbolRef', 'TypeCode']:
                        del legend_entry[element]

            del restriction_on_landownership['Map']  # /definitions/Map

            for item in restriction_on_landownership.get('Geometry', []):
                self._multilingual_text(item, 'ResponsibleOffice_Name')

            legal_provisions = {}
            laws = {}
            hints = {}

            if 'LegalProvisions' in restriction_on_landownership:
                finish = False
                while not finish:
                    finish = True
                    for legal_provision in restriction_on_landownership[
                            'LegalProvisions']:
                        if 'Base64TextAtWeb' in legal_provision:
                            del legal_provision['Base64TextAtWeb']
                        if 'Reference' in legal_provision:
                            for reference in legal_provision['Reference']:
                                self._categorize_documents(
                                    reference, legal_provisions, laws, hints)
                            del legal_provision['Reference']
                            finish = False
                        if 'Article' in legal_provision:
                            for article in legal_provision['Article']:
                                self._categorize_documents(
                                    article, legal_provisions, laws, hints)
                            del legal_provision['Article']
                            finish = False

                        self._categorize_documents(legal_provision,
                                                   legal_provisions, laws,
                                                   hints)

                del restriction_on_landownership['LegalProvisions']

            restriction_on_landownership['LegalProvisions'] = legal_provisions
            restriction_on_landownership['Laws'] = laws
            restriction_on_landownership['Hints'] = hints

        # One restriction entry per theme
        theme_restriction = {}
        text_element = [
            'Information', 'Lawstatus_Code', 'Lawstatus_Text', 'SymbolRef',
            'TypeCode'
        ]
        legend_element = [
            'TypeCode', 'TypeCodelist', 'AreaShare', 'PartInPercent',
            'LengthShare', 'NrOfPoints', 'SymbolRef', 'Information'
        ]
        split_sub_themes = Config.get('print', {}).get('split_sub_themes',
                                                       False)
        for restriction_on_landownership in extract_dict.get(
                'RealEstate_RestrictionOnLandownership', []):
            theme = restriction_on_landownership['Theme_Code']

            if split_sub_themes:
                if 'SubTheme' in restriction_on_landownership:
                    theme = theme + '_' + restriction_on_landownership[
                        'SubTheme']
                    restriction_on_landownership['Split_SubTheme'] = True

            geom_type = \
                'AreaShare' if 'AreaShare' in restriction_on_landownership else \
                'LengthShare' if 'LengthShare' in restriction_on_landownership else 'NrOfPoints'

            if theme not in theme_restriction:
                current = dict(restriction_on_landownership)
                current['Geom_Type'] = geom_type
                theme_restriction[theme] = current

                # Legend
                legend = {}
                for element in legend_element:
                    if element in current:
                        legend[element] = current[element]
                        del current[element]
                    legend['Geom_Type'] = geom_type
                current['Legend'] = [legend]

                # Text
                for element in text_element:
                    if element in current:
                        current[element] = set([current[element]])
                    else:
                        current[element] = set()
                continue
            current = theme_restriction[theme]

            if 'Geom_Type' in current and current['Geom_Type'] != geom_type:
                del current['Geom_Type']

            # Legend
            legend = {}
            for element in legend_element:
                if element in restriction_on_landownership:
                    legend[element] = restriction_on_landownership[element]
                    del restriction_on_landownership[element]
                    legend['Geom_Type'] = geom_type
            current['Legend'].append(legend)

            # Remove in OtherLegend elements that are already in the legend
            current['OtherLegend'] = [
                other_legend_element
                for other_legend_element in current['OtherLegend']
                if other_legend_element['SymbolRef'] != legend['SymbolRef']
            ]

            # Number or array
            for element in ['Laws', 'LegalProvisions', 'Hints']:
                if current.get(
                        element
                ) is not None and restriction_on_landownership.get(
                        element) is not None:
                    current[element].update(
                        restriction_on_landownership[element])
                elif restriction_on_landownership.get(element) is not None:
                    current[element] = restriction_on_landownership[element]

            # add additional ResponsibleOffice to theme if it not already exists there
            new_responsible_office = restriction_on_landownership[
                'ResponsibleOffice'][0]
            existing_office_names = list(
                map(lambda o: o['Name'], current['ResponsibleOffice']))
            if new_responsible_office['Name'] not in existing_office_names:
                current['ResponsibleOffice'].append(new_responsible_office)

            # Text
            for element in text_element:
                if element in restriction_on_landownership:
                    current[element].add(restriction_on_landownership[element])

        for restriction_on_landownership in theme_restriction.values():
            for element in text_element:
                restriction_on_landownership[element] = '\n'.join(
                    restriction_on_landownership[element])
            for element in ['Laws', 'LegalProvisions', 'Hints']:
                values = list(restriction_on_landownership[element].values())
                self.lpra_flatten(values)
                restriction_on_landownership[element] = values
                if element == 'LegalProvisions':
                    # This adds the first URL of TextAtWeb to the pdf_to_join set. At this point of the code
                    # there should only be one URL as the grouping takes place only after this if statement.
                    pdf_to_join.update([
                        legal_provision['TextAtWeb'][0]['URL']
                        for legal_provision in values
                    ])

                # Group legal provisions and hints which have the same title.
                if ((Config.get('print', {}).get('group_legal_provisions',
                                                 False)) and
                    (element == 'LegalProvisions' or element == 'Hints')):
                    restriction_on_landownership[element] = \
                        self.group_legal_provisions(restriction_on_landownership[element])

            # sort legal provisioning, hints and laws
            restriction_on_landownership[
                'LegalProvisions'] = self.sort_dict_list(
                    restriction_on_landownership['LegalProvisions'],
                    self.sort_legal_provision)
            restriction_on_landownership['Laws'] = self.sort_dict_list(
                restriction_on_landownership['Laws'], self.sort_laws)
            restriction_on_landownership['Hints'] = self.sort_dict_list(
                restriction_on_landownership['Hints'], self.sort_hints)

        restrictions = list(theme_restriction.values())
        for restriction in restrictions:
            legends = {}
            for legend in restriction['Legend']:
                type_ = legend['TypeCode']
                if type_ in legends:
                    for item in [
                            'AreaShare', 'LengthShare', 'PartInPercent',
                            'NrOfPoints'
                    ]:
                        if item in legend:
                            if item in legends[type_]:
                                legends[type_][item] += legend[item]
                            else:
                                legends[type_][item] = legend[item]
                else:
                    legends[type_] = legend
            # After transformation, get the new legend entries, sorted by TypeCode
            transformed_legend = \
                list([transformed_entry for (key, transformed_entry) in legends.items()])
            restriction['Legend'] = self.sort_dict_list(
                transformed_legend, self.sort_legend_elem)

        sorted_restrictions = []
        if split_sub_themes:
            # sort sub themes if sub theme splitting is enabled
            sorted_restrictions = self._sort_sub_themes(restrictions)
        else:
            # default sorting
            for theme in Config.get_themes():
                for restriction in restrictions:
                    if theme.code == restriction.get('Theme_Code'):
                        sorted_restrictions.append(restriction)

        extract_dict[
            'RealEstate_RestrictionOnLandownership'] = sorted_restrictions
        # End one restriction entry per theme

        for item in extract_dict.get('ExclusionOfLiability', []):
            self._multilingual_text(item, 'Title')
            self._multilingual_text(item, 'Content')

        extract_dict['features'] = {
            'features': {
                'type':
                'FeatureCollection',
                'features': [{
                    'type': 'Feature',
                    'geometry': feature_geometry,
                    'properties': {}
                }]
            }
        }

        # Reformat land registry area
        extract_dict['RealEstate_LandRegistryArea'] = u'{0} m²'.format(
            extract_dict['RealEstate_LandRegistryArea'])

        # Reformat AreaShare, LengthShare, NrOfPoints and part in percent values
        for restriction in extract_dict[
                'RealEstate_RestrictionOnLandownership']:
            for legend in restriction['Legend']:
                if 'LengthShare' in legend:
                    legend['LengthShare'] = '{0} m'.format(
                        legend['LengthShare'])
                if 'AreaShare' in legend:
                    legend['AreaShare'] = u'{0} m²'.format(legend['AreaShare'])
                if 'PartInPercent' in legend:
                    legend['PartInPercent'] = '{0}%'.format(
                        round(legend['PartInPercent'], 2))
                if 'NrOfPoints' in legend:
                    legend['NrOfPoints'] = '{0}'.format(legend['NrOfPoints'])

        log.debug(
            "After transformation, extract_dict is {}".format(extract_dict))
        return extract_dict
Пример #6
0
    def convert_to_printable_extract(self, extract_dict, feature_geometry,
                                     pdf_to_join):
        """
        Converts an oereb extract into a form suitable for printing by mapfish print.

        Args:
            extract_dict: the oereb extract, will get converted by this function into a form
                            convenient for mapfish-print
            feature_geometry: the geometry for this extract, will get added to the extract information
            pdf_to_join: a set of additional information for the pdf, will get filled by this function
        """

        log.debug(
            "Starting transformation, extract_dict is {}".format(extract_dict))
        log.debug("Parameter feature_geometry is {}".format(feature_geometry))

        creation_date = datetime.strptime(extract_dict['CreationDate'],
                                          '%Y-%m-%dT%H:%M:%S')
        extract_dict['Footer'] = '   '.join([
            creation_date.strftime('%d.%m.%Y'),
            creation_date.strftime('%H:%M:%S'),
            extract_dict['ExtractIdentifier']
        ])
        extract_dict['CreationDate'] = creation_date.strftime('%d.%m.%Y')

        for attr_name in [
                'NotConcernedTheme', 'ThemeWithoutData', 'ConcernedTheme'
        ]:
            for theme in extract_dict[attr_name]:
                self._localised_text(theme, 'Text')
        self._flatten_object(extract_dict, 'PLRCadastreAuthority')
        self._flatten_object(extract_dict, 'RealEstate')
        if 'Image' in extract_dict.get('RealEstate_Highlight', {}):
            del extract_dict['RealEstate_Highlight']['Image']

        main_page_url, main_page_params = \
            parse_url(extract_dict['RealEstate_PlanForLandRegisterMainPage']['ReferenceWMS'])
        base_url = urlparse.urlunsplit(
            (main_page_url.scheme, main_page_url.netloc, main_page_url.path,
             None, None))
        main_page_basemap = {
            'type':
            'wms',
            'styles':
            'default',
            'opacity':
            extract_dict['RealEstate_PlanForLandRegisterMainPage'].get(
                'layerOpacity', 0.6),
            'baseURL':
            base_url,
            'layers':
            main_page_params['LAYERS'][0].split(','),
            'imageFormat':
            'image/png',
            'customParams': {
                'TRANSPARENT': 'true'
            },
        }
        extract_dict['baseLayers'] = {'layers': [main_page_basemap]}
        url, params = parse_url(
            extract_dict['RealEstate_PlanForLandRegister']['ReferenceWMS'])
        basemap = {
            'type':
            'wms',
            'styles':
            'default',
            'opacity':
            extract_dict['RealEstate_PlanForLandRegister'].get(
                'layerOpacity', 0.6),
            'baseURL':
            urlparse.urlunsplit(
                (url.scheme, url.netloc, url.path, None, None)),
            'layers':
            params['LAYERS'][0].split(','),
            'imageFormat':
            'image/png',
            'customParams': {
                'TRANSPARENT': 'true'
            },
        }
        del extract_dict['RealEstate_PlanForLandRegister']  # /definitions/Map

        self._multilingual_m_text(extract_dict, 'GeneralInformation')
        self._multilingual_m_text(extract_dict, 'BaseData')
        self._multilingual_m_text(extract_dict, 'Certification')

        for item in extract_dict.get('Glossary', []):
            self._multilingual_text(item, 'Title')
            self._multilingual_text(item, 'Content')
        self._multilingual_text(extract_dict, 'PLRCadastreAuthority_Name')

        for restriction_on_landownership in extract_dict.get(
                'RealEstate_RestrictionOnLandownership', []):
            self._flatten_object(restriction_on_landownership, 'Lawstatus')
            self._flatten_object(restriction_on_landownership, 'Theme')
            self._flatten_object(restriction_on_landownership,
                                 'ResponsibleOffice')
            self._flatten_array_object(restriction_on_landownership,
                                       'Geometry', 'ResponsibleOffice')
            self._localised_text(restriction_on_landownership, 'Theme_Text')
            self._localised_text(restriction_on_landownership,
                                 'Lawstatus_Text')
            self._multilingual_m_text(restriction_on_landownership,
                                      'Information')
            self._multilingual_text(restriction_on_landownership,
                                    'ResponsibleOffice_Name')

            url, params = parse_url(
                restriction_on_landownership['Map']['ReferenceWMS'])
            restriction_on_landownership['baseLayers'] = {
                'layers': [{
                    'type':
                    'wms',
                    'opacity':
                    restriction_on_landownership['Map'].get(
                        'layerOpacity', 0.6),
                    'styles':
                    'default',
                    'baseURL':
                    urlparse.urlunsplit(
                        (url.scheme, url.netloc, url.path, None, None)),
                    'layers':
                    params['LAYERS'][0].split(','),
                    'imageFormat':
                    'image/png',
                    'customParams': {
                        'TRANSPARENT': 'true'
                    },
                }, basemap]
            }
            restriction_on_landownership[
                'legend'] = restriction_on_landownership['Map'].get(
                    'LegendAtWeb', '')

            # Legend of other visible restriction objects in the topic map
            restriction_on_landownership[
                'OtherLegend'] = restriction_on_landownership['Map'].get(
                    'OtherLegend', [])
            for legend_item in restriction_on_landownership['OtherLegend']:
                self._multilingual_text(legend_item, 'LegendText')

            elementsToDelete = []
            for legend_entry in restriction_on_landownership['OtherLegend']:
                for element in legend_entry.keys():
                    if element not in ['LegendText', 'SymbolRef', 'TypeCode']:
                        elementsToDelete.append(element)

            for elementToDelete in elementsToDelete:
                del legend_entry[elementToDelete]

            del restriction_on_landownership['Map']  # /definitions/Map

            for item in restriction_on_landownership.get('Geometry', []):
                self._multilingual_text(item, 'ResponsibleOffice_Name')

            legal_provisions = {}
            laws = {}
            hints = {}

            if 'LegalProvisions' in restriction_on_landownership:
                finish = False
                while not finish:
                    finish = True
                    for legal_provision in restriction_on_landownership[
                            'LegalProvisions']:
                        if 'Base64TextAtWeb' in legal_provision:
                            del legal_provision['Base64TextAtWeb']
                        if 'Reference' in legal_provision:
                            for reference in legal_provision['Reference']:
                                self._categorize_documents(
                                    reference, legal_provisions, laws, hints)
                            del legal_provision['Reference']
                            finish = False
                        if 'Article' in legal_provision:
                            for article in legal_provision['Article']:
                                self._categorize_documents(
                                    article, legal_provisions, laws, hints)
                            del legal_provision['Article']
                            finish = False

                        self._categorize_documents(legal_provision,
                                                   legal_provisions, laws,
                                                   hints)

                del restriction_on_landownership['LegalProvisions']

            restriction_on_landownership['LegalProvisions'] = legal_provisions
            restriction_on_landownership['Laws'] = laws
            restriction_on_landownership['Hints'] = hints

        # One restriction entry per theme
        theme_restriction = {}
        text_element = [
            'Information', 'Lawstatus_Code', 'Lawstatus_Text',
            'ResponsibleOffice_Name', 'ResponsibleOffice_OfficeAtWeb',
            'SymbolRef', 'TypeCode'
        ]
        legend_element = [
            'TypeCode', 'TypeCodelist', 'AreaShare', 'PartInPercent',
            'LengthShare', 'SymbolRef', 'Information'
        ]
        for restriction_on_landownership in extract_dict.get(
                'RealEstate_RestrictionOnLandownership', []):
            theme = restriction_on_landownership['Theme_Code']
            geom_type = \
                'AreaShare' if 'AreaShare' in restriction_on_landownership else \
                'LengthShare' if 'LengthShare' in restriction_on_landownership else 'NrOfPoints'

            if theme not in theme_restriction:
                current = dict(restriction_on_landownership)
                current['Geom_Type'] = geom_type
                theme_restriction[theme] = current

                # Legend
                legend = {}
                for element in legend_element:
                    if element in current:
                        legend[element] = current[element]
                        del current[element]
                    legend['Geom_Type'] = geom_type
                current['Legend'] = [legend]

                # Text
                for element in text_element:
                    if element in current:
                        current[element] = set([current[element]])
                    else:
                        current[element] = set()
                continue
            current = theme_restriction[theme]

            if 'Geom_Type' in current and current['Geom_Type'] != geom_type:
                del current['Geom_Type']

            # Legend
            legend = {}
            for element in legend_element:
                if element in restriction_on_landownership:
                    legend[element] = restriction_on_landownership[element]
                    del restriction_on_landownership[element]
                    legend['Geom_Type'] = geom_type
            current['Legend'].append(legend)

            # Remove in OtherLegend elements that are already in the legend
            current['OtherLegend'] = [
                other_legend_element
                for other_legend_element in current['OtherLegend']
                if other_legend_element['SymbolRef'] != legend['SymbolRef']
            ]

            # Number or array
            for element in ['Laws', 'LegalProvisions', 'Hints']:
                if current.get(
                        element
                ) is not None and restriction_on_landownership.get(
                        element) is not None:
                    current[element].update(
                        restriction_on_landownership[element])
                elif restriction_on_landownership.get(element) is not None:
                    current[element] = restriction_on_landownership[element]

            # Text
            for element in text_element:
                if element in restriction_on_landownership:
                    current[element].add(restriction_on_landownership[element])

        for restriction_on_landownership in theme_restriction.values():
            for element in text_element:
                restriction_on_landownership[element] = '\n'.join(
                    restriction_on_landownership[element])
            for element in ['Laws', 'LegalProvisions', 'Hints']:
                values = list(restriction_on_landownership[element].values())
                self.lpra_flatten(values)
                restriction_on_landownership[element] = values
                if element is 'LegalProvisions':
                    pdf_to_join.update([
                        legal_provision['TextAtWeb']
                        for legal_provision in values
                    ])

        restrictions = list(theme_restriction.values())
        for restriction in restrictions:
            legends = {}
            for legend in restriction['Legend']:
                type_ = legend['TypeCode']
                if type_ in legends:
                    for item in ['AreaShare', 'LengthShare', 'PartInPercent']:
                        if item in legend:
                            if item in legends[type_]:
                                legends[type_][item] += legend[item]
                            else:
                                legends[type_][item] = legend[item]
                else:
                    legends[type_] = legend
            for legend in legends.values():
                for item in ['AreaShare', 'LengthShare']:
                    if item in legend:
                        legend[item] = legend[item]
            # After transformation, get the new legend entries, sorted by TypeCode
            transformed_legend = \
                list([transformed_entry for (key, transformed_entry) in sorted(legends.items())])
            restriction['Legend'] = transformed_legend
        sorted_restrictions = []
        for theme in Config.get_themes():
            for restriction in restrictions:
                if theme.code == restriction.get('Theme_Code'):
                    sorted_restrictions.append(restriction)
        extract_dict[
            'RealEstate_RestrictionOnLandownership'] = sorted_restrictions
        # End one restriction entry per theme

        for item in extract_dict.get('ExclusionOfLiability', []):
            self._multilingual_text(item, 'Title')
            self._multilingual_text(item, 'Content')

        extract_dict['features'] = {
            'features': {
                'type':
                'FeatureCollection',
                'features': [{
                    'type': 'Feature',
                    'geometry': feature_geometry,
                    'properties': {}
                }]
            }
        }

        # Reformat land registry area
        extract_dict['RealEstate_LandRegistryArea'] = u'{0} m²'.format(
            extract_dict['RealEstate_LandRegistryArea'])

        # Reformat AreaShare, LengthShare and part in percent values
        for restriction in extract_dict[
                'RealEstate_RestrictionOnLandownership']:
            for legend in restriction['Legend']:
                if 'LengthShare' in legend:
                    legend['LengthShare'] = '{0} m'.format(
                        legend['LengthShare'])
                if 'AreaShare' in legend:
                    legend['AreaShare'] = u'{0} m²'.format(legend['AreaShare'])
                if 'PartInPercent' in legend:
                    legend['PartInPercent'] = '{0}%'.format(
                        legend['PartInPercent'])

        log.debug(
            "After transformation, extract_dict is {}".format(extract_dict))
        return extract_dict