diff --git a/georeference/admin.py b/georeference/admin.py index fd401662..8b1d03bb 100644 --- a/georeference/admin.py +++ b/georeference/admin.py @@ -3,12 +3,9 @@ from .models import ( SplitDocumentLink, GeoreferencedDocumentLink, - SplitEvaluation, - GeoreferenceSession, GCP, GCPGroup, LayerMask, - MaskSession, PrepSession, GeorefSession, TrimSession, @@ -16,18 +13,13 @@ class GCPAdmin(admin.ModelAdmin): readonly_fields = ('last_modified',) - -class GeoreferenceSessionAdmin(admin.ModelAdmin): - readonly_fields = ('created',) + list_display = ('id', 'gcp_group') admin.site.register(SplitDocumentLink) -admin.site.register(SplitEvaluation) admin.site.register(GeoreferencedDocumentLink) -admin.site.register(GeoreferenceSession, GeoreferenceSessionAdmin) admin.site.register(GCP, GCPAdmin) admin.site.register(GCPGroup) admin.site.register(LayerMask) -admin.site.register(MaskSession) class SessionAdmin(admin.ModelAdmin): readonly_fields = ('date_created', 'date_modified', 'date_run') diff --git a/georeference/components/src/Georeference.svelte b/georeference/components/src/Georeference.svelte index b0bcd1ce..8df9e8c0 100644 --- a/georeference/components/src/Georeference.svelte +++ b/georeference/components/src/Georeference.svelte @@ -25,6 +25,7 @@ import Projection from 'ol/proj/Projection'; import {transformExtent} from 'ol/proj'; import MousePosition from 'ol/control/MousePosition'; +import ScaleLine from 'ol/control/ScaleLine'; import {createStringXY} from 'ol/coordinate'; import Draw from 'ol/interaction/Draw'; @@ -396,6 +397,11 @@ function MapViewer (elementId) { }); map.addControl(mousePositionControl); + let scaleLine = new ScaleLine({ + units: 'us', + }); + map.addControl(scaleLine) + // add some click actions to the map map.on("click", function(e) { let found = false; diff --git a/georeference/components/src/GeoreferencePreamble.svelte b/georeference/components/src/GeoreferencePreamble.svelte index 26e785bc..c6bea30a 100644 --- a/georeference/components/src/GeoreferencePreamble.svelte +++ b/georeference/components/src/GeoreferencePreamble.svelte @@ -132,7 +132,7 @@ function setPanel(show) { {/if} {#if showVideo}
-

coming soon!

+

View

{/if} diff --git a/georeference/components/src/SplitPreamble.svelte b/georeference/components/src/SplitPreamble.svelte index ae1cc553..d2ca653b 100644 --- a/georeference/components/src/SplitPreamble.svelte +++ b/georeference/components/src/SplitPreamble.svelte @@ -130,7 +130,7 @@ function setPanel(show) { {/if} {#if showVideo}
-

coming soon!

+

View

{/if} diff --git a/georeference/management/commands/mogrify.py b/georeference/management/commands/mogrify.py index f36510c8..4b392fb8 100644 --- a/georeference/management/commands/mogrify.py +++ b/georeference/management/commands/mogrify.py @@ -36,10 +36,10 @@ def handle(self, *args, **options): Layer, gmodels.GCP, gmodels.GCPGroup, - gmodels.GeoreferenceSession, + gmodels.GeorefSession, gmodels.SplitDocumentLink, gmodels.LayerMask, - gmodels.MaskSession, + gmodels.TrimSession, ] for model in model_list: diff --git a/georeference/migrations/0004_auto_20220412_1500.py b/georeference/migrations/0004_auto_20220412_1500.py new file mode 100644 index 00000000..990e5100 --- /dev/null +++ b/georeference/migrations/0004_auto_20220412_1500.py @@ -0,0 +1,38 @@ +# Generated by Django 2.2.20 on 2022-04-12 15:00 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('georeference', '0003_georefsession_prepsession_sessionbase_trimsession'), + ] + + operations = [ + migrations.RemoveField( + model_name='masksession', + name='layer', + ), + migrations.RemoveField( + model_name='masksession', + name='user', + ), + migrations.RemoveField( + model_name='splitevaluation', + name='document', + ), + migrations.RemoveField( + model_name='splitevaluation', + name='user', + ), + migrations.DeleteModel( + name='GeoreferenceSession', + ), + migrations.DeleteModel( + name='MaskSession', + ), + migrations.DeleteModel( + name='SplitEvaluation', + ), + ] diff --git a/georeference/models.py b/georeference/models.py index eacf6318..3562e78a 100644 --- a/georeference/models.py +++ b/georeference/models.py @@ -12,9 +12,11 @@ from django.contrib.gis.db import models from django.contrib.postgres.fields import JSONField from django.core.files import File +from django.db.models import signals from django.utils import timezone from geonode.documents.models import Document, DocumentResourceLink +from geonode.geoserver.signals import geoserver_post_save from geonode.layers.models import Layer, Style from geonode.layers.utils import file_upload from geonode.thumbs.thumbnails import create_thumbnail @@ -68,313 +70,6 @@ def __str__(self): layer_name = "None" return f"{self.document.__str__()} --> {layer_name}" -class SplitEvaluation(models.Model): - """DEPRECATED - will be fully removed in 0.1.0-beta 1""" - - class Meta: - verbose_name = "Split Evaluation" - verbose_name_plural = "Split Evaluations" - - document = models.ForeignKey(Document, on_delete=models.CASCADE) - split_needed = models.BooleanField(default=None, null=True, blank=True) - cutlines = JSONField(default=None, null=True, blank=True) - divisions = JSONField(default=None, null=True, blank=True) - user = models.ForeignKey( - settings.AUTH_USER_MODEL, - blank=True, - null=True, - on_delete=models.CASCADE) - created = models.DateTimeField( - auto_now_add=True, - null=False, - blank=False) - - def __str__(self): - return f"{self.document.__str__()} - {self.user} - {self.created}" - - @property - def georeferenced_downstream(self): - """Returns True if the related document or its children (if it - has been split) have already been georeferenced.""" - - if self.split_needed is True: - docs_to_check = self.get_children() - else: - docs_to_check = [self.document] - - tkm = TKeywordManager() - return any([tkm.is_georeferenced(d) for d in docs_to_check]) - - def get_children(self): - """Returns a list of all the child documents created by this - determination.""" - - ct = ContentType.objects.get(app_label="documents", model="document") - child_ids = SplitDocumentLink.objects.filter( - document=self.document, - content_type=ct, - ).values_list("object_id", flat=True) - return list(Document.objects.filter(pk__in=child_ids)) - - def preview_divisions(self): - - if self.cutlines is None: - return [] - - s = Splitter(image_file=self.document.doc_file.path) - return s.generate_divisions(self.cutlines) - - def run(self): - """ - Runs the document split process based on prestored segmentation info - that has been generated for this document. New Documents are made for - each child image, SplitDocumentLinks are created to link this parent - Document with its children. The parent document is also marked as - metadata_only so that it no longer shows up in the search page lists. - """ - - tkm = TKeywordManager() - tkm.set_status(self.document, "splitting") - - if self.split_needed is False: - tkm.set_status(self.document, "prepared") - self.document.metadata_only = False - self.document.save() - else: - s = Splitter(image_file=self.document.doc_file.path) - s.generate_divisions(self.cutlines) - new_images = s.split_image() - - for n, file_path in enumerate(new_images, start=1): - - fname = os.path.basename(file_path) - new_doc = Document.objects.get(pk=self.document.pk) - new_doc.pk = None - new_doc.id = None - new_doc.uuid = None - new_doc.thumbnail_url = None - new_doc.metadata_only = False - new_doc.title = f"{self.document.title} [{n}]" - with open(file_path, "rb") as openf: - new_doc.doc_file.save(fname, File(openf)) - new_doc.save() - - os.remove(file_path) - - ct = ContentType.objects.get(app_label="documents", model="document") - SplitDocumentLink.objects.create( - document=self.document, - content_type=ct, - object_id=new_doc.pk, - ) - - for r in self.document.regions.all(): - new_doc.regions.add(r) - tkm.set_status(new_doc, "prepared") - - if len(new_images) > 1: - self.document.metadata_only = True - self.document.save() - - tkm.set_status(self.document, "split") - - return - - def cleanup(self): - """Method called with pre_delete signal that cleans up resulting - documents from previous split operations, if necessary. This is - meant to provide a "reset" capability for SplitDeterminations.""" - - # first check to make sure this determination can be reversed. - if self.georeferenced_downstream is True: - logger.warn(f"Removing SplitEvaluation {self.pk} even though downstream georeferencing has occurred.") - - # if a split was made, remove all descendant documents before deleting - if self.split_needed is True: - for child in self.get_children(): - child.delete() - - SplitDocumentLink.objects.filter(document=self.document).delete() - - TKeywordManager().set_status(self.document, "unprepared") - self.document.metadata_only = False - self.document.save() - - def serialize(self): - return { - "allow_reset": not self.georeferenced_downstream, - "user": { - "name": self.user.username, - "profile": full_reverse("profile_detail", args=(self.user.username, )), - }, - "date": (self.created.month, self.created.day, self.created.year), - "date_str": self.created.strftime("%Y-%m-%d"), - "datetime": self.created.strftime("%Y-%m-%d - %H:%M"), - "split_needed": self.split_needed, - "divisions_ct": len(self.get_children()), - } - - - -class GeoreferenceSession(models.Model): - """DEPRECATED - will be fully removed in 0.1.0-beta 1""" - class Meta: - verbose_name = "Georeference Session" - verbose_name_plural = "Georeference Sessions" - - document = models.ForeignKey(Document, on_delete=models.CASCADE) - layer = models.ForeignKey(Layer, models.SET_NULL, null=True, blank=True) - gcps_used = JSONField(null=True, blank=True) - transformation_used = models.CharField(null=True, blank=True, max_length=20) - crs_epsg_used = models.IntegerField(null=True, blank=True) - user = models.ForeignKey( - settings.AUTH_USER_MODEL, - blank=True, - null=True, - on_delete=models.CASCADE) - created = models.DateTimeField( - auto_now_add=True, - editable=False, - null=False, - blank=False) - status = models.CharField( - default="initializing", - max_length=100, - ) - note = models.CharField( - blank=True, - null=True, - max_length=255, - ) - - def __str__(self): - return f"{self.document.title} - {self.created}" - - def run(self): - - tkm = TKeywordManager() - tkm.set_status(self.document, "georeferencing") - self.update_status("initializing georeferencer") - try: - g = Georeferencer( - transformation=self.transformation_used, - epsg_code=self.crs_epsg_used, - ) - g.load_gcps_from_geojson(self.gcps_used) - except Exception as e: - self.update_status("failed") - self.note = f"{e.message}" - self.save() - # revert to previous tkeyword status - tkm.set_status(self.document, "prepared") - return None - self.update_status("georeferencing") - try: - out_path = g.make_tif(self.document.doc_file.path) - except Exception as e: - self.update_status("failed") - self.note = f"{e.message}" - self.save() - # revert to previous tkeyword status - tkm.set_status(self.document, "prepared") - return None - - # self.transformation_used = g.transformation["id"] - self.update_status("creating layer") - - ## need to remove commas from the titles, otherwise the layer will not - ## be valid in the catalog list when trying to add it to a Map. the - ## message in the catalog will read "Missing OGC reference metadata". - title = self.document.title.replace(",", " -") - - ## first look to see if there is a layer alreaded linked to this document. - ## this would indicate that it has already been georeferenced, and in this - ## case the existing layer should be overwritten. - existing_layer = None - try: - link = GeoreferencedDocumentLink.objects.get(document=self.document) - existing_layer = Layer.objects.get(pk=link.object_id) - except (GeoreferencedDocumentLink.DoesNotExist, Layer.DoesNotExist): - pass - - ## create the layer, passing in the existing_layer if present - layer = file_upload( - out_path, - layer=existing_layer, - overwrite=True, - title=title, - user=self.user, - ) - - ## if there was no existing layer, create a new link between the - ## document and the new layer - if existing_layer is None: - ct = ContentType.objects.get(app_label="layers", model="layer") - GeoreferencedDocumentLink.objects.create( - document=self.document, - content_type=ct, - object_id=layer.pk, - ) - - # set attributes in the layer straight from the document - for keyword in self.document.keywords.all(): - layer.keywords.add(keyword) - for region in self.document.regions.all(): - layer.regions.add(region) - Layer.objects.filter(pk=layer.pk).update( - date=self.document.date, - abstract=self.document.abstract, - category=self.document.category, - license=self.document.license, - restriction_code_type=self.document.restriction_code_type, - attribution=self.document.attribution, - ) - - ## if there was an existing layer that's been overwritten, regenerate thumb. - else: - self.update_status("regenerating thumbnail") - thumb = create_thumbnail(layer, overwrite=True) - Layer.objects.filter(pk=layer.pk).update(thumbnail_url=thumb) - - self.layer = layer - self.update_status("saving control points") - - # save the successful gcps to the canonical GCPGroup for the document - GCPGroup().save_from_geojson( - self.gcps_used, - self.document, - self.transformation_used - ) - - tkm.set_status(self.document, "georeferenced") - tkm.set_status(layer, "georeferenced") - - self.update_status("completed") - self.save() - - return layer - - def update_status(self, status): - logger.debug(f"GeoreferenceSession {self.id} | set status: {status}") - self.status = status - self.save(update_fields=['status']) - - def serialize(self): - return { - "user": { - "name": self.user.username, - "profile": full_reverse("profile_detail", args=(self.user.username, )), - }, - "date": (self.created.month, self.created.day, self.created.year), - "date_str": self.created.strftime("%Y-%m-%d"), - "datetime": self.created.strftime("%Y-%m-%d - %H:%M"), - "gcps_geojson": self.gcps_used, - "gcps_ct": len(self.gcps_used["features"]), - "transformation": self.transformation_used, - "epsg": self.crs_epsg_used, - "status": self.status, - } - class GCP(models.Model): @@ -627,108 +322,9 @@ def apply_mask(self): self.layer.save() # update thumbnail with new trim style - thumb = create_thumbnail(self.layer, overwrite=True) - self.layer.thumbnail_url = thumb - self.layer.save() - -class MaskSession(models.Model): - """DEPRECATED - will be fully removed in 0.1.0-beta 1""" - class Meta: - verbose_name = "Mask Session" - verbose_name_plural = "Mask Sessions" - - layer = models.ForeignKey(Layer, on_delete=models.CASCADE) - polygon = models.PolygonField(null=True, blank=True, srid=3857) - user = models.ForeignKey( - settings.AUTH_USER_MODEL, - blank=True, - null=True, - on_delete=models.CASCADE) - created = models.DateTimeField( - auto_now_add=True, - editable=False, - null=False, - blank=False) - note = models.CharField( - blank=True, - null=True, - max_length=255, - ) - - def run(self): - - ## first get the related Document so the statuses can be managed - ct = ContentType.objects.get(app_label="layers", model="layer") - document = GeoreferencedDocumentLink.objects.get( - content_type=ct, - object_id=self.layer.pk, - ).document - - tkm = TKeywordManager() - tkm.set_status(self.layer, "trimming") - tkm.set_status(document, "trimming") - - # create/update a LayerMask for this layer and apply it as style - if self.polygon is not None: - - try: - mask = LayerMask.objects.get(layer=self.layer) - mask.polygon = self.polygon - mask.save() - except LayerMask.DoesNotExist: - mask = LayerMask.objects.create( - layer=self.layer, - polygon=self.polygon, - ) - mask.apply_mask() - - tkm.set_status(self.layer, "trimmed") - tkm.set_status(document, "trimmed") - - # if there is no polygon, then clean up old mask styles and reset the - # default style to original (if needed) - else: - - # delete the LayerMask object - LayerMask.objects.filter(layer=self.layer).delete() - - # delete the existing trim style in Geoserver if necessary - cat = get_gs_catalog() - trim_style_name = f"{self.layer.name}_trim" - gs_trim_style = cat.get_style(trim_style_name, workspace="geonode") - if gs_trim_style is not None: - cat.delete(gs_trim_style, recurse=True) - - # delete the existing trimmed style in GeoNode - Style.objects.filter(name=trim_style_name).delete() - - # set the full style back to the default in GeoNode - gn_full_style = Style.objects.get(name=self.layer.name) - self.layer.default_style = gn_full_style - self.layer.save() - - # update thumbnail - thumb = create_thumbnail(self.layer, overwrite=True) - self.layer.thumbnail_url = thumb - self.layer.save() - - tkm.set_status(self.layer, "georeferenced") - tkm.set_status(document, "georeferenced") - - def serialize(self): - vertex_ct = 0 - if self.polygon is not None: - vertex_ct = len(self.polygon.coords[0]) - 1 - return { - "user": { - "name": self.user.username, - "profile": full_reverse("profile_detail", args=(self.user.username, )), - }, - "date": (self.created.month, self.created.day, self.created.year), - "date_str": self.created.strftime("%Y-%m-%d"), - "datetime": self.created.strftime("%Y-%m-%d - %H:%M"), - "vertex_ct": vertex_ct, - } +# thumb = create_thumbnail(self.layer, overwrite=True) +# self.layer.thumbnail_url = thumb +# self.layer.save() def get_default_session_data(session_type): """Return a dict of the keys/types for a sessions's data field. @@ -1115,7 +711,7 @@ def undo(self): # first check to make sure this determination can be reversed. if self.georeferenced_downstream is True: - logger.warn(f"Removing SplitEvaluation {self.pk} even though downstream georeferencing has occurred.") + logger.warn(f"Removing PrepSession {self.pk} even though downstream georeferencing has occurred.") # if a split was made, remove all descendant documents before deleting for child in self.get_children(): @@ -1193,6 +789,8 @@ def run(self): tkm = TKeywordManager() tkm.set_status(self.document, "georeferencing") + signals.post_save.disconnect(geoserver_post_save, sender=Layer) + self.date_run = timezone.now() self.update_stage("processing", save=False) self.update_status("initializing georeferencer", save=False) @@ -1275,12 +873,6 @@ def run(self): attribution=self.document.attribution, ) - ## if there was an existing layer that's been overwritten, regenerate thumb. - else: - self.update_status("regenerating thumbnail") - thumb = create_thumbnail(layer, overwrite=True) - Layer.objects.filter(pk=layer.pk).update(thumbnail_url=thumb) - self.layer = layer self.update_status("saving control points") @@ -1291,6 +883,15 @@ def run(self): self.data['transformation'], ) + ## now reconnect the geoserver post_save receiver and run final layer save. + signals.post_save.connect(geoserver_post_save, sender=Layer) + layer.save() + + if existing_layer is not None: + self.update_status("regenerating thumbnail") + thumb = create_thumbnail(layer, overwrite=True) + Layer.objects.filter(pk=layer.pk).update(thumbnail_url=thumb) + tkm.set_status(self.document, "georeferenced") tkm.set_status(layer, "georeferenced") @@ -1450,7 +1051,7 @@ def undo(self): LayerMask.objects.filter(layer=self.layer).delete() - self.set_status("unapplied") + self.update_status("unapplied") def save(self, *args, **kwargs): self.type = 't' diff --git a/georeference/proxy_models.py b/georeference/proxy_models.py index e046e4f9..f74c7a44 100644 --- a/georeference/proxy_models.py +++ b/georeference/proxy_models.py @@ -285,14 +285,15 @@ def get_best_region_extent(self): be an aggregation of all regions on the highest level (i.e. two adjacent towns). """ - use_polygon = Polygon.from_bbox((-180, -90, 180, 90)) - for region in self.resource.regions.all(): + # hard-code default Louisiana extent for now + use_polygon = Polygon.from_bbox((-94, 28, -88, 33)) + for region in self.resource.regions.all().exclude(name="Global").exclude(name="Louisiana"): polygon = Polygon.from_bbox(region.bbox[:4]) if polygon.area < use_polygon.area: use_polygon = polygon region_extent = use_polygon.extent return region_extent - + def get_extended_urls(self): urls = self.urls urls.update(self.get_layer_urls()) diff --git a/loc_insurancemaps/api.py b/loc_insurancemaps/api.py index 4fa7beb7..45058b76 100644 --- a/loc_insurancemaps/api.py +++ b/loc_insurancemaps/api.py @@ -241,23 +241,6 @@ def import_volume(self, identifier): return volume - def import_sheets(self, volume_id): - - vol = Volume.objects.get(identifier=volume_id) - - sheets = [] - for fileset in vol.lc_resources[0]['files']: - info = LOCParser().parse_fileset(fileset) - if self.dry_run: - continue - try: - sheet = Sheet.objects.get(volume=vol, sheet_no=info["sheet_number"]) - except Sheet.DoesNotExist: - sheet = Sheet().create_from_fileset(fileset, vol, fileset_info=info) - sheets.append(sheet) - - return sheets - def initialize_volume(self, volume): """Creates all of the necessary items to begin georeferencing a new volume. diff --git a/loc_insurancemaps/components/src/Volume.svelte b/loc_insurancemaps/components/src/Volume.svelte index 45fcd008..312bf36b 100644 --- a/loc_insurancemaps/components/src/Volume.svelte +++ b/loc_insurancemaps/components/src/Volume.svelte @@ -41,11 +41,12 @@ export let MAPBOX_API_KEY; $: sheetsLoading = VOLUME.status == "initializing..."; let loadTip = false; +let previewMapTip = false; let map; let layersPresent = VOLUME.ordered_layers.layers.length != 0 || VOLUME.ordered_layers.index_layers.length != 0; let showMap = layersPresent -let showUnprepared = false; +let showUnprepared = VOLUME.status == "initializing..."; let showPrepared = false; let showGeoreferenced = false; @@ -145,7 +146,7 @@ function initMap() { map = new Map({ target: "map", // controls: defaultControls().extend([new FullScreen(), new ZoomToExtent()]), - maxTilesLoading: 200, + maxTilesLoading: 50, }); const osmLayer = new TileLayer({ source: new OSM(), @@ -307,8 +308,10 @@ function setLayersFromVolume(setExtent) { 'TILED': true, }, tileGrid: tileGrid, - }) + }), + extent: transformExtent(layerDef.extent, "EPSG:4326", "EPSG:3857") }); + layerRegistry[layerDef.geoserver_id] = newLayer; mainGroup.getLayers().push(newLayer) }); @@ -331,6 +334,7 @@ function setLayersFromVolume(setExtent) { }, tileGrid: tileGrid, }), + extent: transformExtent(layerDef.extent, "EPSG:4326", "EPSG:3857") }); layerRegistry[layerDef.geoserver_id] = newLayer; keyGroup.getLayers().push(newLayer) @@ -349,6 +353,15 @@ function setLayerOrder(newOrder, topZ) { $: setLayerOrder(orderableLayers, 500) $: setLayerOrder(orderableIndexLayers, 50) +let intervalId; +function manageAutoReload(run) { + if (run) { + intervalId = setInterval(postOperation, 4000, "refresh"); + } else { + clearInterval(intervalId) + } +} +$: manageAutoReload(sheetsLoading) function postOperation(operation) { let layerIds = []; @@ -479,27 +492,23 @@ function handleKeyup(e) { {/each}

{/if} - {#if VOLUME.sheet_ct.loaded == 0 && USER_TYPE != 'anonymous' && !sheetsLoading} + {#if VOLUME.sheet_ct.loaded < VOLUME.sheet_ct.total && USER_TYPE != 'anonymous' && !sheetsLoading} {/if} - {#if USER_TYPE == 'anonymous' } -
-

- - sign in or - sign up to work on this content -

-
- {/if}

Map Overview

-
-

The preview map shows progress toward a full mosaic of this volume's content.

-
-

showMap = !showMap}> - - Preview Map ({VOLUME.items.layers.length} layers) +

+ showMap = !showMap}> + + Preview Map ({VOLUME.items.layers.length} layers) + + previewMapTip = !previewMapTip}>

+ {#if previewMapTip} +
+

The preview map shows progress toward a full mosaic of this volume's content. Please note: it is not optimized for performance and may be sluggish for large cities. The best way to view a single layer is find it in the Georeferenced section below and click the thumbnail.

+
+ {/if}
@@ -592,15 +601,41 @@ function handleKeyup(e) {
- {#if VOLUME.loaded_by.name != "" && !sheetsLoading} + +

+ + {#if sheetsLoading} + Loading sheet {VOLUME.sheet_ct.loaded+1}/{VOLUME.sheet_ct.total}... (you can safely leave this page). + {:else if VOLUME.sheet_ct.loaded == 0} + No sheets loaded yet... + {:else if VOLUME.sheet_ct.loaded < VOLUME.sheet_ct.total } + {VOLUME.sheet_ct.loaded} of {VOLUME.sheet_ct.total} sheet{#if VOLUME.sheet_ct.total != 1}s{/if} loaded (initial load unsuccessful. Click Load Volume to retry) + {:else} + {VOLUME.sheet_ct.loaded} of {VOLUME.sheet_ct.total} sheet{#if VOLUME.sheet_ct.total != 1}s{/if} loaded by {VOLUME.loaded_by.name} - {VOLUME.loaded_by.date} + {/if} +

+ {#if sheetsLoading} +
{/if} + +
+ + {#if USER_TYPE == 'anonymous' } +
+

+ + sign in or + sign up to work on this content +

+ {/if}

showUnprepared = !showUnprepared}> @@ -732,6 +767,9 @@ function handleKeyup(e) {
  • trim →
  • edit georeferencing →
  • layer detail →
  • + + + {/if} {#if settingKeyMapLayer} diff --git a/loc_insurancemaps/components/src/Volumes.svelte b/loc_insurancemaps/components/src/Volumes.svelte index 409861b0..40656b78 100644 --- a/loc_insurancemaps/components/src/Volumes.svelte +++ b/loc_insurancemaps/components/src/Volumes.svelte @@ -14,17 +14,18 @@ export let STARTED_VOLUMES; {:else} - Community - Year - Sheets - Loaded by - U - P - G + Community + Year + Sheets + Loaded by + U + P + G + % - {v.city}, {v.county_equivalent} + {v.city}, {v.county_equivalent} {v.year_vol} {v.sheet_ct} @@ -32,6 +33,7 @@ export let STARTED_VOLUMES; {v.unprepared_ct} {v.prepared_ct} {v.georeferenced_ct} +
    {/if} @@ -40,6 +42,22 @@ export let STARTED_VOLUMES;