def map_info(request): geo_utils = GeoUtils() if settings.DEFAULT_BOUNDS is not None: hex_bin_bounds = geo_utils.get_bounds_from_geojson(settings.DEFAULT_BOUNDS) default_center = geo_utils.get_centroid(settings.DEFAULT_BOUNDS) else: hex_bin_bounds = (0, 0, 1, 1) default_center = {"coordinates": [6.602384, 0.245926]} # an island off the coast of Africa query = GroupMapSettings.objects.filter(group=request.user.groups.all()[0]) if query.exists(): group_map_settings = query.first() min_zoom = group_map_settings.min_zoom max_zoom = group_map_settings.max_zoom default_zoom = group_map_settings.default_zoom else: min_zoom = settings.MAP_MIN_ZOOM max_zoom = settings.MAP_MAX_ZOOM default_zoom = settings.DEFAULT_MAP_ZOOM return { "map_info": { "x": default_center["coordinates"][0], "y": default_center["coordinates"][1], "zoom": default_zoom, "map_min_zoom": min_zoom, "map_max_zoom": max_zoom, "mapbox_api_key": settings.MAPBOX_API_KEY, "hex_bin_size": settings.HEX_BIN_SIZE if settings.HEX_BIN_SIZE is not None else 100, "mapbox_sprites": settings.MAPBOX_SPRITES, "mapbox_glyphs": settings.MAPBOX_GLYPHS, "hex_bin_bounds": json.dumps(hex_bin_bounds), "geocoder_default": settings.DEFAULT_GEOCODER, "preferred_coordinate_systems": JSONSerializer().serialize(settings.PREFERRED_COORDINATE_SYSTEMS), } }
def map_info(request): geo_utils = GeoUtils() hex_bin_bounds = geo_utils.get_bounds_from_geojson(settings.DEFAULT_BOUNDS) default_center = geo_utils.get_centroid(settings.DEFAULT_BOUNDS) return { 'map_info': { 'x': default_center['coordinates'][0], 'y': default_center['coordinates'][1], 'zoom': settings.DEFAULT_MAP_ZOOM, 'map_min_zoom': settings.MAP_MIN_ZOOM, 'map_max_zoom': settings.MAP_MAX_ZOOM, 'mapbox_api_key': settings.MAPBOX_API_KEY, 'mapzen_api_key': settings.MAPZEN_API_KEY, 'hex_bin_size': settings.HEX_BIN_SIZE if settings.HEX_BIN_SIZE != None else 100, 'mapbox_sprites': settings.MAPBOX_SPRITES, 'mapbox_glyphs': settings.MAPBOX_GLYPHS, 'hex_bin_bounds': json.dumps(hex_bin_bounds), 'geocoder_default': settings.DEFAULT_GEOCODER, 'preferred_coordinate_systems': JSONSerializer().serialize(settings.PREFERRED_COORDINATE_SYSTEMS) } }
def serialize_for_mobile(self): """ serialize to a different form than used by the internal class structure used to append additional values (like parent ontology properties) that internal objects (like models.Nodes) don't support """ serializer = JSONSerializer() serializer.geom_format = 'geojson' obj = serializer.handle_model(self) ordered_cards = self.get_ordered_cards() expired = (datetime.strptime(str(self.enddate), '%Y-%m-%d') - datetime.now() + timedelta(hours=24)).days < 0 ret = JSONSerializer().serializeToPython(obj) if expired: self.active = False super(MobileSurvey, self).save() ret['active'] = False graphs = [] card_lookup = {} for card in self.cards.all(): if str(card.graph_id) in card_lookup: card_lookup[str(card.graph_id)].append(card) else: card_lookup[str(card.graph_id)] = [card] for graphid, cards in iter(card_lookup.items()): graph = Graph.objects.get(pk=graphid) graph_obj = graph.serialize(exclude=['domain_connections', 'edges', 'relatable_resource_model_ids']) graph_obj['widgets'] = list(models.CardXNodeXWidget.objects.filter(card__graph=graph).distinct()) nodegroupids = [] for card in cards: topcard = Card.objects.get(pk=card.cardid) self.collect_card_widget_node_data(graph_obj, graph, topcard, nodegroupids) graph_obj['widgets'] = serializer.serializeToPython(graph_obj['widgets']) nodegroup_filters = {'nodes': 'nodegroup_id', 'cards': 'nodegroup_id', 'nodegroups': 'nodegroupid'} for prop, id in iter(nodegroup_filters.items()): relevant_items = [item for item in graph_obj[prop] if item[id] in nodegroupids] graph_obj[prop] = relevant_items relevant_cardids = [card['cardid'] for card in graph_obj['cards']] relevant_widgets = [widget for widget in graph_obj['widgets'] if str(widget['card_id']) in relevant_cardids] graph_obj['widgets'] = relevant_widgets graphs.append(serializer.serializeToPython(graph_obj)) ret['graphs'] = graphs ret['cards'] = ordered_cards try: bounds = json.loads(ret['bounds']) ret['bounds'] = bounds if (bounds['type'] == 'MultiPolygon'): singlepart = GeoUtils().convert_multipart_to_singlepart(bounds) ret['bounds'] = singlepart except TypeError as e: print 'Could not parse', ret['bounds'], e return ret
def map_info(request): geo_utils = GeoUtils() hex_bin_bounds = geo_utils.get_bounds_from_geojson(settings.DEFAULT_BOUNDS) default_center = geo_utils.get_centroid(settings.DEFAULT_BOUNDS) return { 'map_info': { 'x': default_center['coordinates'][0], 'y': default_center['coordinates'][1], 'zoom': settings.DEFAULT_MAP_ZOOM, 'map_min_zoom': settings.MAP_MIN_ZOOM, 'map_max_zoom': settings.MAP_MAX_ZOOM, 'mapbox_api_key': settings.MAPBOX_API_KEY, 'hex_bin_size': settings.HEX_BIN_SIZE if settings.HEX_BIN_SIZE != None else 100, 'mapbox_sprites': settings.MAPBOX_SPRITES, 'mapbox_glyphs': settings.MAPBOX_GLYPHS, 'hex_bin_bounds': json.dumps(hex_bin_bounds), 'geocoder_default': settings.DEFAULT_GEOCODER, 'preferred_coordinate_systems': JSONSerializer().serialize(settings.PREFERRED_COORDINATE_SYSTEMS) } }
def __init__(self, search_request=None): if search_request is None: raise Exception("Need to pass in a search request") search_request.GET = search_request.GET.copy() search_request.GET["tiles"] = True search_request.GET["export"] = True self.compact = search_request.GET.get("compact", True) self.precision = int(search_request.GET.get("precision", 5)) self.search_request = search_request self.datatype_factory = DataTypeFactory() self.node_lookup = {} self.output = {} self.set_precision = GeoUtils().set_precision
def __init__(self, search_request=None): if search_request is None: raise Exception("Need to pass in a search request") search_request.GET = search_request.GET.copy() search_request.GET["tiles"] = True search_request.GET["export"] = True self.format = search_request.GET.get("format", "tilecsv") self.compact = search_request.GET.get("compact", True) self.precision = int(search_request.GET.get("precision", 5)) if self.format == "shp" and self.compact is not True: raise Exception("Results must be compact to export to shapefile") self.search_request = search_request self.datatype_factory = DataTypeFactory() self.node_lookup = {} self.output = {} self.set_precision = GeoUtils().set_precision
def serialize(self, fields=None, exclude=None): """ serialize to a different form than used by the internal class structure used to append additional values (like parent ontology properties) that internal objects (like models.Nodes) don't support """ serializer = JSONSerializer() serializer.geom_format = "geojson" obj = serializer.handle_model(self) ordered_cards = self.get_ordered_cards() ret = JSONSerializer().serializeToPython(obj) ret["cards"] = ordered_cards try: bounds = json.loads(ret["bounds"]) ret["bounds"] = bounds if bounds["type"] == "MultiPolygon": singlepart = GeoUtils().convert_multipart_to_singlepart(bounds) ret["bounds"] = singlepart except TypeError as e: print("Could not parse", ret["bounds"], e) return ret
def serialize_for_mobile(self): """ serialize to a different form than used by the internal class structure used to append additional values (like parent ontology properties) that internal objects (like models.Nodes) don't support """ serializer = JSONSerializer() serializer.geom_format = "geojson" obj = serializer.handle_model(self) ordered_cards = self.get_ordered_cards() expired = False try: expired = (datetime.strptime(str(self.enddate), "%Y-%m-%d") - datetime.now() + timedelta(hours=24)).days < 0 except ValueError: pass ret = JSONSerializer().serializeToPython(obj) if expired is True: self.active = False super(MobileSurvey, self).save() ret["active"] = False graphs = [] card_lookup = {} for card in self.cards.all(): if str(card.graph_id) in card_lookup: card_lookup[str(card.graph_id)].append(card) else: card_lookup[str(card.graph_id)] = [card] for graphid, cards in iter(list(card_lookup.items())): graph = Graph.objects.get(pk=graphid) graph_obj = graph.serialize(exclude=[ "domain_connections", "edges", "relatable_resource_model_ids" ]) graph_obj["widgets"] = list( models.CardXNodeXWidget.objects.filter( card__graph=graph).distinct()) nodegroupids = [] for card in cards: topcard = Card.objects.get(pk=card.cardid) self.collect_card_widget_node_data(graph_obj, graph, topcard, nodegroupids) graph_obj["widgets"] = serializer.serializeToPython( graph_obj["widgets"]) nodegroup_filters = { "nodes": "nodegroup_id", "cards": "nodegroup_id", "nodegroups": "nodegroupid" } for prop, id in iter(list(nodegroup_filters.items())): relevant_items = [ item for item in graph_obj[prop] if item[id] in nodegroupids ] graph_obj[prop] = relevant_items relevant_cardids = [card["cardid"] for card in graph_obj["cards"]] relevant_widgets = [ widget for widget in graph_obj["widgets"] if str(widget["card_id"]) in relevant_cardids ] graph_obj["widgets"] = relevant_widgets graphs.append(serializer.serializeToPython(graph_obj)) ret["graphs"] = graphs ret["cards"] = ordered_cards try: bounds = json.loads(ret["bounds"]) ret["bounds"] = bounds if bounds["type"] == "MultiPolygon": singlepart = GeoUtils().convert_multipart_to_singlepart(bounds) ret["bounds"] = singlepart except TypeError as e: logger.error("Could not parse {0}, {1}".format(ret["bounds"], e)) return ret
def seed_resource_cache(): datatype_factory = DataTypeFactory() zooms = range(settings.CACHE_SEED_MAX_ZOOM + 1) extension = 'pbf' lat1, lon1, lat2, lon2 = GeoUtils().get_bounds_from_geojson( settings.CACHE_SEED_BOUNDS) south, west = min(lat1, lat2), min(lon1, lon2) north, east = max(lat1, lat2), max(lon1, lon2) northwest = Location(north, west) southeast = Location(south, east) padding = 0 datatypes = [ d.pk for d in models.DDataType.objects.filter(isgeometric=True) ] nodes = models.Node.objects.filter(graph__isresource=True, datatype__in=datatypes) for node in nodes: datatype = datatype_factory.get_instance(node.datatype) count = models.TileModel.objects.filter( data__has_key=str(node.nodeid)).count() if datatype.should_cache(node) and count > 0: config = TileStache.parseConfig(get_tileserver_config(node.nodeid)) layer = config.layers[str(node.nodeid)] ul = layer.projection.locationCoordinate(northwest) lr = layer.projection.locationCoordinate(southeast) coordinates = generateCoordinates(ul, lr, zooms, padding) for (offset, count, coord) in coordinates: path = '%s/%d/%d/%d.%s' % (layer.name(), coord.zoom, coord.column, coord.row, extension) progress = {"tile": path, "offset": offset + 1, "total": count} attempts = 3 rendered = False while not rendered: print '%(offset)d of %(total)d...' % progress, try: mimetype, content = TileStache.getTile( layer, coord, extension, True) except: attempts -= 1 print 'Failed %s, will try %s more.' % ( progress['tile'], ['no', 'once', 'twice' ][attempts]) if attempts == 0: print 'Failed %(zoom)d/%(column)d/%(row)d, trying next tile.\n' % coord.__dict__ break else: rendered = True progress['size'] = '%dKB' % (len(content) / 1024) print '%(tile)s (%(size)s)' % progress
def get(self, request): def get_last_login(date): result = _("Not yet logged in") try: if date is not None: result = datetime.strftime(date, '%Y-%m-%d %H:%M') except TypeError as e: print e return result identities = [] for group in Group.objects.all(): users = group.user_set.all() if len(users) > 0: groupUsers = [{'id': user.id, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email, 'last_login': get_last_login(user.last_login), 'username': user.username, 'groups': [g.id for g in user.groups.all()], 'group_names': ', '.join([g.name for g in user.groups.all()]) } for user in users] identities.append({'name': group.name, 'type': 'group', 'id': group.pk, 'users': groupUsers, 'default_permissions': group.permissions.all()}) for user in User.objects.filter(): groups = [] group_ids = [] default_perms = [] for group in user.groups.all(): groups.append(group.name) group_ids.append(group.id) default_perms = default_perms + list(group.permissions.all()) identities.append({'name': user.email or user.username, 'groups': ', '.join(groups), 'type': 'user', 'id': user.pk, 'default_permissions': set(default_perms), 'is_superuser':user.is_superuser, 'group_ids': group_ids, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email}) map_layers = models.MapLayer.objects.all() map_markers = models.MapMarker.objects.all() map_sources = models.MapSource.objects.all() geocoding_providers = models.Geocoder.objects.all() mobile_survey_models = models.MobileSurveyModel.objects.order_by('name') mobile_surveys, resources = self.get_survey_resources(mobile_survey_models) for mobile_survey in mobile_surveys: try: mobile_survey['datadownloadconfig'] = json.loads(mobile_survey['datadownloadconfig']) except TypeError: pass multipart = mobile_survey['bounds'] singlepart = GeoUtils().convert_multipart_to_singlepart(multipart) mobile_survey['bounds'] = singlepart serializer = JSONSerializer() context = self.get_context_data( map_layers=map_layers, map_markers=map_markers, map_sources=map_sources, geocoding_providers=geocoding_providers, mobile_surveys=serializer.serialize(mobile_surveys, sort_keys=False), identities=serializer.serialize(identities, sort_keys=False), resources=serializer.serialize(resources, sort_keys=False), resource_download_limit=settings.MOBILE_DOWNLOAD_RESOURCE_LIMIT, main_script='views/mobile-survey-manager', ) context['nav']['title'] = _('Mobile Survey Manager') context['nav']['icon'] = 'fa-server' context['nav']['help'] = { 'title': _('Mobile Survey Manager'), 'template': 'mobile-survey-manager-help', } return render(request, 'views/mobile-survey-manager.htm', context)
def get(self, request): datatype_factory = DataTypeFactory() set_precision = GeoUtils().set_precision resourceid = request.GET.get("resourceid", None) nodeid = request.GET.get("nodeid", None) tileid = request.GET.get("tileid", None) nodegroups = request.GET.get("nodegroups", []) precision = request.GET.get("precision", 9) field_name_length = int(request.GET.get("field_name_length", 0)) use_uuid_names = bool(request.GET.get("use_uuid_names", False)) include_primary_name = bool( request.GET.get("include_primary_name", False)) include_geojson_link = bool( request.GET.get("include_geojson_link", False)) use_display_values = bool(request.GET.get("use_display_values", False)) geometry_type = request.GET.get("type", None) indent = request.GET.get("indent", None) if indent is not None: indent = int(indent) if isinstance(nodegroups, str): nodegroups = nodegroups.split(",") if hasattr(request.user, "userprofile") is not True: models.UserProfile.objects.create(user=request.user) viewable_nodegroups = request.user.userprofile.viewable_nodegroups nodegroups = [i for i in nodegroups if i in viewable_nodegroups] nodes = models.Node.objects.filter( datatype="geojson-feature-collection", nodegroup_id__in=viewable_nodegroups) if nodeid is not None: nodes = nodes.filter(nodeid=nodeid) nodes = nodes.order_by("sortorder") features = [] i = 1 property_tiles = models.TileModel.objects.filter( nodegroup_id__in=nodegroups).order_by("sortorder") property_node_map = {} property_nodes = models.Node.objects.filter( nodegroup_id__in=nodegroups).order_by("sortorder") for node in property_nodes: property_node_map[str(node.nodeid)] = {"node": node} if node.fieldname is None or node.fieldname == "": property_node_map[str(node.nodeid)]["name"] = slugify( node.name, max_length=field_name_length, separator="_") else: property_node_map[str(node.nodeid)]["name"] = node.fieldname for node in nodes: tiles = models.TileModel.objects.filter( nodegroup=node.nodegroup).order_by("sortorder") if resourceid is not None: tiles = tiles.filter( resourceinstance_id__in=resourceid.split(",")) if tileid is not None: tiles = tiles.filter(tileid=tileid) for tile in tiles: data = tile.data try: for feature_index, feature in enumerate(data[str( node.pk)]["features"]): if geometry_type is None or geometry_type == feature[ "geometry"]["type"]: if len(nodegroups) > 0: for pt in property_tiles.filter( resourceinstance_id=tile. resourceinstance_id): for key in pt.data: field_name = key if use_uuid_names else property_node_map[ key]["name"] if pt.data[key] is not None: if use_display_values: property_node = property_node_map[ key]["node"] datatype = datatype_factory.get_instance( property_node.datatype) value = datatype.get_display_value( pt, property_node) else: value = pt.data[key] try: feature["properties"][ field_name].append(value) except KeyError: feature["properties"][ field_name] = value except AttributeError: feature["properties"][ field_name] = [ feature["properties"] [field_name], value ] if include_primary_name: feature["properties"][ "primary_name"] = self.get_name( tile.resourceinstance) feature["properties"][ "resourceinstanceid"] = tile.resourceinstance_id feature["properties"]["tileid"] = tile.pk if nodeid is None: feature["properties"]["nodeid"] = node.pk if include_geojson_link: feature["properties"][ "geojson"] = "%s?tileid=%s&nodeid=%s" % ( reverse("geojson"), tile.pk, node.pk) feature["id"] = i coordinates = set_precision( feature["geometry"]["coordinates"], precision) feature["geometry"]["coordinates"] = coordinates i += 1 features.append(feature) except KeyError: pass except TypeError as e: print(e) print(tile.data) response = JSONResponse( { "type": "FeatureCollection", "features": features }, indent=indent) return response
def get(self, request, surveyid): def get_history(survey, history): sync_log_records = models.MobileSyncLog.objects.order_by( '-finished').values().filter(survey=survey) resourceedits = models.TileRevisionLog.objects.filter( survey=survey).values('resourceid').annotate( Count('tileid', distinct=True)) if len(sync_log_records) > 0: lastsync = datetime.strftime(sync_log_records[0]['finished'], '%Y-%m-%d %H:%M:%S') history['lastsync'] = lastsync for entry in sync_log_records: history['edits'] = len(resourceedits) if entry['user'] not in history['editors']: history['editors'][entry['user']] = { 'edits': entry['tilesupdated'], 'lastsync': entry['finished'] } else: history['editors'][ entry['user']]['edits'] += entry['tilesupdated'] if entry['finished'] > history['editors'][ entry['user']]['lastsync']: history['editors'][ entry['user']]['lastsync'] = entry['finished'] for id, editor in iter(history['editors'].items()): editor['lastsync'] = datetime.strftime(editor['lastsync'], '%Y-%m-%d %H:%M:%S') return history identities = [] for group in Group.objects.all(): users = group.user_set.all() if len(users) > 0: groupUsers = [{ 'id': user.id, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email, 'username': user.username, 'groups': [g.id for g in user.groups.all()], 'group_names': ', '.join([g.name for g in user.groups.all()]) } for user in users] identities.append({ 'name': group.name, 'type': 'group', 'id': group.pk, 'users': groupUsers, 'default_permissions': group.permissions.all() }) for user in User.objects.filter(): groups = [] group_ids = [] default_perms = [] for group in user.groups.all(): groups.append(group.name) group_ids.append(group.id) default_perms = default_perms + list(group.permissions.all()) identities.append({ 'name': user.email or user.username, 'groups': ', '.join(groups), 'type': 'user', 'id': user.pk, 'default_permissions': set(default_perms), 'is_superuser': user.is_superuser, 'group_ids': group_ids, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email }) history = {'lastsync': '', 'edits': 0, 'editors': {}} map_layers = models.MapLayer.objects.all() map_markers = models.MapMarker.objects.all() map_sources = models.MapSource.objects.all() geocoding_providers = models.Geocoder.objects.all() survey_exists = models.MobileSurveyModel.objects.filter( pk=surveyid).exists() if survey_exists is True: survey = MobileSurvey.objects.get(pk=surveyid) mobile_survey = survey.serialize() history = get_history(survey, history) resources = get_survey_resources(mobile_survey) else: survey = MobileSurvey( id=surveyid, name=_(''), datadownloadconfig={ "download": False, "count": 100, "resources": [], "custom": None }, onlinebasemaps=settings.MOBILE_DEFAULT_ONLINE_BASEMAP, ) mobile_survey = survey.serialize() mobile_survey['bounds'] = settings.DEFAULT_BOUNDS resources = get_survey_resources(mobile_survey) try: mobile_survey['datadownloadconfig'] = json.loads( mobile_survey['datadownloadconfig']) except TypeError: pass try: if mobile_survey['bounds']['type'] == 'MultiPolygon': multipart = mobile_survey['bounds'] singlepart = GeoUtils().convert_multipart_to_singlepart( multipart) mobile_survey['bounds'] = singlepart except TypeError as e: pass serializer = JSONSerializer() context = self.get_context_data( map_layers=map_layers, map_markers=map_markers, map_sources=map_sources, history=serializer.serialize(history), geocoding_providers=geocoding_providers, mobile_survey=serializer.serialize(mobile_survey, sort_keys=False), identities=serializer.serialize(identities, sort_keys=False), resources=serializer.serialize(resources, sort_keys=False), resource_download_limit=mobile_survey['datadownloadconfig'] ['count'], main_script='views/mobile-survey-designer', ) context['nav']['menu'] = True context['nav']['title'] = _('Mobile Survey Manager') context['nav']['icon'] = 'fa-server' context['nav']['help'] = { 'title': _('Mobile Survey Manager'), 'template': 'mobile-survey-manager-help', } return render(request, 'views/mobile-survey-designer.htm', context)
def get(self, request, surveyid): def get_history(survey, history): sync_log_records = models.MobileSyncLog.objects.order_by("-finished").values().filter(survey=survey) resourceedits = ( models.TileRevisionLog.objects.filter(survey=survey).values("resourceid").annotate(Count("tileid", distinct=True)) ) if len(sync_log_records) > 0: lastsync = datetime.strftime(sync_log_records[0]["finished"], "%Y-%m-%d %H:%M:%S") history["lastsync"] = lastsync for entry in sync_log_records: history["edits"] = len(resourceedits) if entry["userid"] not in history["editors"]: history["editors"][entry["userid"]] = {"lastsync": entry["finished"]} else: if entry["finished"] > history["editors"][entry["userid"]]["lastsync"]: history["editors"][entry["userid"]]["lastsync"] = entry["finished"] for id, editor in iter(list(history["editors"].items())): editor["lastsync"] = datetime.strftime(editor["lastsync"], "%Y-%m-%d %H:%M:%S") return history identities = [] for group in Group.objects.all(): users = group.user_set.all() if len(users) > 0: groupUsers = [ { "id": user.id, "first_name": user.first_name, "last_name": user.last_name, "email": user.email, "username": user.username, "groups": [g.id for g in user.groups.all()], "group_names": ", ".join([g.name for g in user.groups.all()]), } for user in users ] identities.append( {"name": group.name, "type": "group", "id": group.pk, "users": groupUsers, "default_permissions": group.permissions.all()} ) for user in User.objects.filter(): groups = [] group_ids = [] default_perms = [] for group in user.groups.all(): groups.append(group.name) group_ids.append(group.id) default_perms = default_perms + list(group.permissions.all()) identities.append( { "name": user.email or user.username, "groups": ", ".join(groups), "type": "user", "id": user.pk, "default_permissions": set(default_perms), "is_superuser": user.is_superuser, "group_ids": group_ids, "first_name": user.first_name, "last_name": user.last_name, "email": user.email, } ) history = {"lastsync": "", "edits": 0, "editors": {}} map_layers = models.MapLayer.objects.all() map_markers = models.MapMarker.objects.all() map_sources = models.MapSource.objects.all() geocoding_providers = models.Geocoder.objects.all() survey_exists = models.MobileSurveyModel.objects.filter(pk=surveyid).exists() if survey_exists is True: survey = MobileSurvey.objects.get(pk=surveyid) mobile_survey = survey.serialize() history = get_history(survey, history) resources = get_survey_resources(mobile_survey) else: survey = MobileSurvey( id=surveyid, name="", datadownloadconfig={"download": False, "count": 100, "resources": [], "custom": None}, onlinebasemaps=settings.MOBILE_DEFAULT_ONLINE_BASEMAP, ) mobile_survey = survey.serialize() mobile_survey["bounds"] = settings.DEFAULT_BOUNDS resources = get_survey_resources(mobile_survey) try: mobile_survey["datadownloadconfig"] = json.loads(mobile_survey["datadownloadconfig"]) except TypeError: pass try: if mobile_survey["bounds"]["type"] == "MultiPolygon": multipart = mobile_survey["bounds"] singlepart = GeoUtils().convert_multipart_to_singlepart(multipart) mobile_survey["bounds"] = singlepart except TypeError as e: pass serializer = JSONSerializer() context = self.get_context_data( map_layers=map_layers, map_markers=map_markers, map_sources=map_sources, history=serializer.serialize(history), geocoding_providers=geocoding_providers, mobile_survey=serializer.serialize(mobile_survey, sort_keys=False), identities=serializer.serialize(identities, sort_keys=False), resources=serializer.serialize(resources, sort_keys=False), resource_download_limit=mobile_survey["datadownloadconfig"]["count"], main_script="views/mobile-survey-designer", ) context["nav"]["menu"] = True context["nav"]["title"] = _("Arches Collector Manager") context["nav"]["icon"] = "fa-globe" context["nav"]["help"] = {"title": _("Arches Collector Manager"), "template": "arches-collector-manager-help"} return render(request, "views/mobile-survey-designer.htm", context)