def _crud_baselayer(self, form): """ CRUD base layer """ if form.cleaned_data['as_base_layer']: # Create/update base layer if self.base_layer: # update self.base_layer.title = form.cleaned_data['base_layer_title'] self.base_layer.description = form.cleaned_data['base_layer_desc'] property = eval(self.base_layer.property) property['attributions'] = form.cleaned_data['base_layer_attr'] self.base_layer.property = property self.base_layer.save() else: # create # create OL config data # i.e.: # { # "crs": { # "epsg": 32632, # "proj4": '+proj=utm +zone=32 +datum=WGS84 +units=m +no_defs', # "geographic": False, # "axisinverted": False # }, # "url": "https://dev.g3wsuite.it/caching/api/qdjango30/{z}/{x}/{y}.png", # "servertype": "TMS", # "attributions": "Ortofoto Piemonte AGEA 2015" # } crs = QgsCoordinateReferenceSystem(f'EPSG:{self.layer.project.group.srid.srid}') property = { "crs": { "epsg": self.layer.project.group.srid.srid, "proj4": crs.toProj4(), "geographic": crs.isGeographic(), "axisinverted": crs.hasAxisInverted() }, "url": f"/caching/api/{self.layer._meta.app_label}{self.layer.pk}/"+"{z}/{x}/{y}.png", "servertype": "TMS", "attributions": form.cleaned_data['base_layer_attr'] } kwargs = { 'name': f'bl_from_cached_layer_{self.layer.pk}', 'title': form.cleaned_data['base_layer_title'], 'description': form.cleaned_data['base_layer_desc'], 'property': property } self.base_layer = BaseLayer(**kwargs) self.base_layer.save() # update caching layer config record self.activated.baselayer_id = self.base_layer.pk self.activated.save() else: # Delete base layer if self.base_layer and self.base_layer.pk: self.base_layer.delete() if self.activated.baselayer_id: self.activated.baselayer_id = None self.activated.save()
def to_representation(self, instance): ret = super(GroupSerializer, self).to_representation(instance) # add header_logo # before check macrogroups and groups number also if is equal to 1 use it try: macrogroup = instance.macrogroups.get(use_logo_client=True) ret['header_logo_img'] = macrogroup.logo_img.name except: ret['header_logo_img'] = instance.header_logo_img.name try: macrogroup = instance.macrogroups.get(use_title_client=True) ret['name'] = macrogroup.title except: # change groupData name with title for i18n app ret['name'] = instance.title # add crs: crs = QgsCoordinateReferenceSystem(f'EPSG:{self.instance.srid.srid}') # Patch for Proj4 > 4.9.3 version if self.instance.srid.srid == 3003: proj4 = settings.PROJ4_EPSG_3003 else: proj4 = crs.toProj4() ret['crs'] = { 'epsg': crs.postgisSrid(), 'proj4': proj4, 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() } # map controls ret['mapcontrols'] = [ mapcontrol.name for mapcontrol in instance.mapcontrols.all() ] # add projects to group ret['projects'] = [] self.projects = {} anonymous_user = get_user_model().get_anonymous() for g3wProjectApp in settings.G3WADMIN_PROJECT_APPS: Project = apps.get_app_config(g3wProjectApp).get_model('project') projects = get_objects_for_user(self.request.user, '{}.view_project'.format(g3wProjectApp), Project) \ .filter(group=instance) projects_anonymous = get_objects_for_user( anonymous_user, '{}.view_project'.format(g3wProjectApp), Project).filter(group=instance) projects = list(set(projects) | set(projects_anonymous)) for project in projects: self.projects[g3wProjectApp + '-' + str(project.id)] = project if project.pk == int( self.projectId) and g3wProjectApp == self.projectType: self.project = project # project thumbnail project_thumb = project.thumbnail.name if bool(project.thumbnail.name) \ else '{}client/images/FakeProjectThumb.png'.format(settings.STATIC_URL) # Get project url if project.url_alias: url = reverse('group-project-map-alias', args=[project.url_alias])[1:] else: url = reverse( 'group-project-map', args=[project.group.slug, g3wProjectApp, project.pk])[1:] ret['projects'].append({ 'id': project.id, 'title': project.title, 'description': project.description, 'thumbnail': project_thumb, 'type': g3wProjectApp, 'gid': "{}:{}".format(g3wProjectApp, project.id), 'modified': project.modified.timestamp() if hasattr( project, 'modified') else 0, 'url': url }) # baselayers ret['baselayers'] = [] baselayers = instance.baselayers.all().order_by('order') for baselayer in baselayers: ret['baselayers'].append(BaseLayerSerializer(baselayer).data) # add vendorkeys if it is set into settings if settings.VENDOR_KEYS: ret['vendorkeys'] = settings.VENDOR_KEYS # add initproject and overviewproject ret['initproject'] = "{}:{}".format(self.projectType, self.projectId) # add overviewproject is present overviewproject = instance.project_panoramic.all() if overviewproject: overviewproject = overviewproject[0] ret['overviewproject'] = { 'id': int(overviewproject.project_id), 'type': overviewproject.project_type, 'gid': "{}:{}".format(overviewproject.project_type, overviewproject.project_id) } else: ret['overviewproject'] = None ret['plugins'] = {} # Plugins/Module data # Data from plugins can be instance of dict or list # - dict results are used only for update 'plugins' API return data # - list results are more verbose and action on 'plugins' API section is declared, ie: # { # 'mode': 'delete', # 'data': [<list_plugins_section_to_remove>] # }, # { # 'mode': 'update', # 'data': { # '<lugins_name>: { # ... # } # } # } plugins = initconfig_plugin_start.send(sender=self, project=self.projectId, projectType=self.projectType) for data_plugin in plugins: if data_plugin[1] and isinstance(data_plugin[1], dict): ret['plugins'] = copy(ret['plugins']) ret['plugins'].update(data_plugin[1]) elif data_plugin[1] and isinstance(data_plugin[1], list): for dp in data_plugin[1]: if dp['mode'] == 'delete': ret['plugins'] = copy(ret['plugins']) for k in dp['data']: try: ret['plugins'].pop(k) except: pass elif dp['mode'] == 'update': ret['plugins'] = copy(ret['plugins']) ret['plugins'].update(dp['data']) # powerd_by ret['powered_by'] = settings.G3WSUITE_POWERD_BY # header customs links header_custom_links = getattr(settings, 'G3W_CLIENT_HEADER_CUSTOM_LINKS', None) ret['header_custom_links'] = [] if header_custom_links: # check for possible callback for head_link in header_custom_links: if callable(head_link): ret['header_custom_links'].append(head_link(self.request)) else: ret['header_custom_links'].append(head_link) # custom layout ret['layout'] = {} # add legend settings if set to layout layout_legend = getattr(settings, 'G3W_CLIENT_LEGEND', None) if layout_legend: ret['layout']['legend'] = layout_legend # Check if G3W_CLIENT_LEGEND['layertitle'] set it tu false if self.project.legend_position == 'toc': if layout_legend: ret['layout']['legend']['layertitle'] = False else: ret['layout']['legend'] = {'layertitle': False} # add legend settings if set to layout layout_right_panel = getattr(settings, 'G3W_CLIENT_RIGHT_PANEL', None) if layout_right_panel: ret['layout']['rightpanel'] = layout_right_panel return ret
def to_representation(self, instance): ret = super(LayerSerializer, self).to_representation(instance) qgs_maplayer = self.qgs_project.mapLayers()[instance.qgs_layer_id] group = instance.project.group # add attributes/fields ret['fields'] = self.get_attributes(instance) # add infoformat and infourl ret['infoformat'] = '' ret['infourl'] = '' lidname = instance.qgs_layer_id if instance.project.wms_use_layer_ids else instance.name # add bbox if instance.geometrytype != QGIS_LAYER_TYPE_NO_GEOM: if instance.extent: ret['bbox'] = instance.extent_rect else: # get from QgsMapLayer instance extent = qgs_maplayer.extent() ret['bbox'] = {} ret['bbox']['minx'] = extent.xMinimum() ret['bbox']['miny'] = extent.yMinimum() ret['bbox']['maxx'] = extent.xMaximum() ret['bbox']['maxy'] = extent.yMaximum() # add capabilities ret['capabilities'] = get_capabilities4layer(qgs_maplayer) # add styles # FIXME: restore in the future for styles map management #ret['styles'] = self.qgis_projectsettings_wms.layers[lidname]['styles'] ret['source'] = {'type': instance.layer_type} # add options for wms layer if instance.layer_type in [ Layer.TYPES.wms, Layer.TYPES.arcgismapserver ]: if instance.layer_type == Layer.TYPES.wms: datasourceWMS = QueryDict(instance.datasource) else: datasourceWMS = datasourcearcgis2dict(instance.datasource) if ('username' not in ret['source'] or 'password' not in ret['source']) and 'type=xyz' \ not in instance.datasource: # rebuild the dict for paramenters repeat n times i.e. 'layers' and 'styles' if isinstance(datasourceWMS, QueryDict): for p in datasourceWMS.lists(): if p[0] in ('layers', 'styles'): ret['source'].update({p[0]: ','.join(p[1])}) else: ret['source'].update({p[0]: datasourceWMS[p[0]]}) else: ret['source'].update(datasourceWMS) ret['source']['external'] = instance.external # replace crs property if is not none with dict structure if ret['crs']: crs = QgsCoordinateReferenceSystem(f'EPSG:{ret["crs"]}') ret['crs'] = { 'epsg': crs.postgisSrid(), 'proj4': crs.toProj4(), 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() } # add metadata ret['metadata'] = self.get_metadata(instance, qgs_maplayer) # eval editor_form_structure if ret['editor_form_structure']: ret['editor_form_structure'] = eval(instance.editor_form_structure) # add ows ret['ows'] = self.get_ows(instance) return ret
def to_representation(self, instance): ret = super(LayerSerializer, self).to_representation(instance) qgs_maplayer = self.qgs_project.mapLayers()[instance.qgs_layer_id] # add attributes/fields ret['fields'] = self.get_attributes(instance) # add infoformat and infourl ret['infoformat'] = '' ret['infourl'] = '' #lidname = instance.qgs_layer_id if instance.project.wms_use_layer_ids else instance.name # add bbox if instance.geometrytype != QGIS_LAYER_TYPE_NO_GEOM: if instance.extent: ret['bbox'] = instance.extent_rect else: # get from QgsMapLayer instance extent = qgs_maplayer.extent() ret['bbox'] = {} ret['bbox']['minx'] = extent.xMinimum() ret['bbox']['miny'] = extent.yMinimum() ret['bbox']['maxx'] = extent.xMaximum() ret['bbox']['maxy'] = extent.yMaximum() # add capabilities ret['capabilities'] = get_capabilities4layer(qgs_maplayer) # add styles # FIXME: restore in the future for styles map management #ret['styles'] = self.qgis_projectsettings_wms.layers[lidname]['styles'] ret['source'] = {'type': instance.layer_type} # add options for wms layer if instance.layer_type in [ Layer.TYPES.wms, Layer.TYPES.arcgismapserver ]: if instance.layer_type == Layer.TYPES.wms: datasource_wms = QueryDict(instance.datasource) else: datasource_wms = datasourcearcgis2dict(instance.datasource) if ('username' not in ret['source'] or 'password' not in ret['source']) and 'type=xyz' \ not in instance.datasource: # rebuild the dict for paramenters repeat n times i.e. 'layers' and 'styles' if isinstance(datasource_wms, QueryDict): for p in datasource_wms.lists(): if p[0] in ('layers', 'styles'): ret['source'].update({p[0]: ','.join(p[1])}) else: ret['source'].update({p[0]: datasource_wms[p[0]]}) else: ret['source'].update(datasource_wms) ret['source']['external'] = instance.external if instance.external and instance.layer_type == Layer.TYPES.wms: try: wms = WebMapService(ret['source']['url'], version='1.3.0') format_options = wms.getOperationByName( 'GetFeatureInfo').formatOptions if format_options: # Filter format by supported by G3W-CLIENT formats = list( set(format_options).intersection( set(settings.EXTERNAL_WMS_INFOFORMATS_SUPPORTED ))) if formats: ret['infoformat'] = formats[0] ret['infoformats'] = formats except Exception as e: logger.debug( f'WMS layer GetFeatureInfo formats available: {e}') # replace crs property if is not none with dict structure if ret['crs']: crs = QgsCoordinateReferenceSystem(f'EPSG:{ret["crs"]}') # Patch for Proj4 > 4.9.3 version if ret["crs"] == 3003: proj4 = "+proj=tmerc +lat_0=0 +lon_0=9 +k=0.9996 +x_0=1500000 +y_0=0 +ellps=intl " \ "+towgs84=-104.1,-49.1,-9.9,0.971,-2.917,0.714,-11.68 +units=m +no_defs" else: proj4 = crs.toProj4() ret['crs'] = { 'epsg': crs.postgisSrid(), 'proj4': proj4, 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() } # add metadata ret['metadata'] = self.get_metadata(instance, qgs_maplayer) # eval editor_form_structure if ret['editor_form_structure']: ret['editor_form_structure'] = eval(instance.editor_form_structure) # add ows ret['ows'] = self.get_ows(instance) # For temporal properties if instance.temporal_properties: ret['qtimeseries'] = json.loads(instance.temporal_properties) if ret['qtimeseries'] and ret['qtimeseries'][ 'mode'] == 'FeatureDateTimeInstantFromField': # Add start_date end end_date: findex = qgs_maplayer.dataProvider().fieldNameIndex( ret['qtimeseries']['field']) ret['qtimeseries']['start_date'] = qgs_maplayer.minimumValue( findex) ret['qtimeseries']['end_date'] = qgs_maplayer.maximumValue( findex) if isinstance(ret['qtimeseries']['start_date'], QDate) or isinstance( ret['qtimeseries']['start_date'], QDateTime): if not hasattr(QDate, 'isoformat'): QDate.isoformat = lambda d: d.toString(Qt.ISODate) if not hasattr(QDateTime, 'isoformat'): QDateTime.isoformat = lambda d: d.toString( Qt.ISODateWithMs) ret['qtimeseries']['start_date'] = ret['qtimeseries'][ 'start_date'].isoformat() ret['qtimeseries']['end_date'] = ret['qtimeseries'][ 'end_date'].isoformat() return ret
def to_representation(self, instance): ret = super(GroupSerializer, self).to_representation(instance) # add header_logo # before check macrogroups and groups number also if is equal to 1 use it try: macrogroup = instance.macrogroups.get(use_logo_client=True) ret['header_logo_img'] = macrogroup.logo_img.name except: ret['header_logo_img'] = instance.header_logo_img.name try: macrogroup = instance.macrogroups.get(use_title_client=True) ret['name'] = macrogroup.title except: # change groupData name with title for i18n app ret['name'] = instance.title # add crs: crs = QgsCoordinateReferenceSystem(f'EPSG:{self.instance.srid.srid}') ret['crs'] = { 'epsg': crs.postgisSrid(), 'proj4': crs.toProj4(), 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() } # map controls ret['mapcontrols'] = [ mapcontrol.name for mapcontrol in instance.mapcontrols.all() ] # add projects to group ret['projects'] = [] self.projects = {} anonymous_user = get_user_model().get_anonymous() for g3wProjectApp in settings.G3WADMIN_PROJECT_APPS: Project = apps.get_app_config(g3wProjectApp).get_model('project') projects = get_objects_for_user(self.request.user, '{}.view_project'.format(g3wProjectApp), Project) \ .filter(group=instance) projects_anonymous = get_objects_for_user( anonymous_user, '{}.view_project'.format(g3wProjectApp), Project).filter(group=instance) projects = list(set(projects) | set(projects_anonymous)) print(projects) for project in projects: self.projects[g3wProjectApp + '-' + str(project.id)] = project if project.pk == int( self.projectId) and g3wProjectApp == self.projectType: self.project = project # project thumbnail project_thumb = project.thumbnail.name if bool(project.thumbnail.name) \ else '{}client/images/FakeProjectThumb.png'.format(settings.STATIC_URL) ret['projects'].append({ 'id': project.id, 'title': project.title, 'description': project.description, 'thumbnail': project_thumb, 'type': g3wProjectApp, 'gid': "{}:{}".format(g3wProjectApp, project.id), 'modified': project.modified.timestamp() if hasattr( project, 'modified') else 0 }) # baselayers ret['baselayers'] = [] baselayers = instance.baselayers.all().order_by('order') for baselayer in baselayers: ret['baselayers'].append(BaseLayerSerializer(baselayer).data) # add vendorkeys if it is set into settings if settings.VENDOR_KEYS: ret['vendorkeys'] = settings.VENDOR_KEYS # add initproject and overviewproject ret['initproject'] = "{}:{}".format(self.projectType, self.projectId) # add overviewproject is present overviewproject = instance.project_panoramic.all() if overviewproject: overviewproject = overviewproject[0] ret['overviewproject'] = { 'id': int(overviewproject.project_id), 'type': overviewproject.project_type, 'gid': "{}:{}".format(overviewproject.project_type, overviewproject.project_id) } else: ret['overviewproject'] = None ret['plugins'] = {} # plugins/module data dataPlugins = initconfig_plugin_start.send( sender=self, project=self.projectId, projectType=self.projectType) for dataPlugin in dataPlugins: if dataPlugin[1]: ret['plugins'] = copy(ret['plugins']) ret['plugins'].update(dataPlugin[1]) # powerd_by ret['powered_by'] = settings.G3WSUITE_POWERD_BY # header customs links header_custom_links = getattr(settings, 'G3W_CLIENT_HEADER_CUSTOM_LINKS', None) ret['header_custom_links'] = [] if header_custom_links: # check for possible callback for head_link in header_custom_links: if callable(head_link): ret['header_custom_links'].append(head_link(self.request)) else: ret['header_custom_links'].append(head_link) # custom layout ret['layout'] = {} # add legend settings if set to layout layout_legend = getattr(settings, 'G3W_CLIENT_LEGEND', None) if layout_legend: ret['layout']['legend'] = layout_legend # Check if G3W_CLIENT_LEGEND['layertitle'] set it tu false if self.project.legend_position == 'toc': if layout_legend: ret['layout']['legend']['layertitle'] = False else: ret['layout']['legend'] = {'layertitle': False} # add legend settings if set to layout layout_right_panel = getattr(settings, 'G3W_CLIENT_RIGHT_PANEL', None) if layout_right_panel: ret['layout']['rightpanel'] = layout_right_panel return ret
def post(self, request, **kwargs): # Check for content type accept only 'application/json' if request.content_type != 'application/json': return APIException( "Interface OWS accept only 'application/json request'") post_data = json.loads(request.body) # Required url = post_data.get('url') if not url: raise APIException("'url' parameter must be provided.") service = post_data.get('service') if not service: raise APIException("'service' parameter must be provided.") service = service.lower() if service not in self._service_available.keys(): raise APIException(f"Service '{service}' is not available.") # Not required: version = post_data.get('version', '1.3.0') ows = self._service_available[service](url, version=version) # Identification # ----------------------------------- self.results.results.update({ 'title': ows.identification.title, 'abstract': ows.identification.abstract }) # Map formats # ----------------------------------- self.results.results.update( {'map_formats': ows.getOperationByName('GetMap').formatOptions}) # Info formats # ----------------------------------- self.results.results.update({ 'info_formats': ows.getOperationByName('GetFeatureInfo').formatOptions }) # Layers # ----------------------------------- available_layers = list(ows.contents) # add styles for every layer layers = [] for al in available_layers: # Build crs crss = [] for srid in ows[al].crsOptions: crs = QgsCoordinateReferenceSystem(srid) if crs.postgisSrid() == 3003: proj4 = settings.PROJ4_EPSG_3003 else: proj4 = crs.toProj4() crss.append({ 'epsg': crs.postgisSrid(), 'proj4': proj4, 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() }) layers.append({ 'name': al, 'title': ows[al].title, 'abstract': ows[al].abstract, 'crss': crss, 'styles': ows[al].styles, 'parent': ows[al].parent.id if ows[al].parent else None }) self.results.results.update({'layers': layers}) return Response(self.results.results)