diff --git a/ohmg/accounts/validators.py b/ohmg/accounts/validators.py new file mode 100644 index 00000000..01d83ffc --- /dev/null +++ b/ohmg/accounts/validators.py @@ -0,0 +1,12 @@ +from django.contrib.auth.validators import UnicodeUsernameValidator + +class OHMGUnicodeUsernameValidator(UnicodeUsernameValidator): + """ + Slight change to UnicodeUsernameValidator so that it doesn't allow @. + """ + regex = r'^[\w.+-]+\Z' + message = "Username may contain only letters, numbers, and . + - _" + +custom_username_validators = [ + OHMGUnicodeUsernameValidator(), +] diff --git a/ohmg/api/api.py b/ohmg/api/api.py index 28d2e9ad..18851702 100644 --- a/ohmg/api/api.py +++ b/ohmg/api/api.py @@ -1,11 +1,11 @@ import logging -from typing import List +from typing import List, Optional from django.conf import settings from django.shortcuts import get_object_or_404 from django.urls import reverse -from ninja import NinjaAPI, Query +from ninja import NinjaAPI, Query, FilterSchema from ninja.pagination import paginate from ninja.security import APIKeyHeader @@ -65,15 +65,45 @@ def list_users(request): queryset = User.objects.all().exclude(username="AnonymousUser").order_by("username") return list(queryset) +class ItemFilterSchema(FilterSchema): + """not currently used, would need to customize the fields a bit""" + loaded_by__username: Optional[str] = None + @api.get('items/', response=List[ItemListSchema], url_name="item_list") -def list_items(request, sort: str = "default", limit: int = None): +def list_items(request, + # filters: ItemFilterSchema = Query(...), + sort: str = "default", + limit: int = None, + loaded: bool = True, + loaded_by: str = None, + locale: str = None, + locale_inclusive: bool = False, + ): + # overall, not really optimized. should refactor at some point... if sort == "load_date": - queryset = Volume.objects.all().exclude(loaded_by=None).order_by('-load_date') + items = Volume.objects.all().order_by('-load_date') else: - queryset = Volume.objects.all().exclude(loaded_by=None).order_by('city', 'year') + items = Volume.objects.all().order_by('city', 'year') + + if locale: + place = Place.objects.get(slug=locale) + if locale_inclusive: + if locale in ['united-states', 'mexico', 'canada', 'cuba']: + pass + else: + pks = place.get_inclusive_pks() + items = items.filter(locales__in=pks) + else: + items = items.filter(locales=place.pk) + + if loaded: + items = items.exclude(loaded_by=None) + if loaded_by: + items = items.filter(loaded_by__username=loaded_by) + if limit: - queryset = queryset[:limit] - return list(queryset) + items = items[:limit] + return list(items) @api.get('places/', response=List[PlaceSchema], url_name="place_list") def list_places(request): diff --git a/ohmg/content/models.py b/ohmg/content/models.py index 5ffe6a03..90d55d7b 100644 --- a/ohmg/content/models.py +++ b/ohmg/content/models.py @@ -271,27 +271,3 @@ def generate_mosaic_json(self, trim_all=False): logger.info(f"{self.vol.identifier} | mosaic created: {os.path.basename(mosaic_json_path)}") return mosaic_json_path - - def generate_mosaic_jpg(self, out_path): - ''' Create a non-geo JPEG version of the COG mosaic. Still a work in progress... - - Ultimately, would like for this JPEG to not have internal overviews, but I haven't - had any luck removing them during the conversion. - - Tried using PIL instead of gdal, but still getting the overviews. PIL can seek "frames" - in the image, and different overviews ARE different frames, but the base data still - seems to include all of the upper overviews! - ''' - - mosaic_vrt = self.generate_mosaic_vrt() - - to = gdal.TranslateOptions( - format="GTiff", - creationOptions = [ - "COMPRESS=JPEG", - "BIGTIFF=YES", - #"INTERNAL_MASK=NO", - ], - ) - - gdal.Translate(out_path, mosaic_vrt, options=to) diff --git a/ohmg/content/schemas.py b/ohmg/content/schemas.py index c983a4c9..e1477809 100644 --- a/ohmg/content/schemas.py +++ b/ohmg/content/schemas.py @@ -100,7 +100,7 @@ def resolve_stats(obj): if obj.multimask is not None: mm_ct = len(obj.multimask) mm_todo = main_lyrs_ct - mm_ct - if mm_ct > 0: + if mm_ct > 0 and main_lyrs_ct > 0: mm_display = f"{mm_ct}/{main_lyrs_ct}" mm_percent = mm_ct / main_lyrs_ct mm_percent += main_lyrs_ct * .000001 diff --git a/ohmg/content/urls.py b/ohmg/content/urls.py new file mode 100644 index 00000000..022ef8b1 --- /dev/null +++ b/ohmg/content/urls.py @@ -0,0 +1,11 @@ +from django.urls import path + +from .views import ( + ItemView, + VirtualResourceView, +) + +urlpatterns = [ + path('item/', ItemView.as_view(), name="resource_detail"), + path('resource/', VirtualResourceView.as_view(), name="resource_detail"), +] diff --git a/ohmg/content/views.py b/ohmg/content/views.py new file mode 100644 index 00000000..821e2a52 --- /dev/null +++ b/ohmg/content/views.py @@ -0,0 +1,124 @@ +import json +import logging +from datetime import datetime + +from django.conf import settings +from django.http import JsonResponse +from django.shortcuts import render, get_object_or_404 +from django.views import View +from django.middleware import csrf +from django.urls import reverse + +from ohmg.georeference.models import ( + Layer, + Document, + ItemBase, +) +from ohmg.loc_insurancemaps.models import Volume, find_volume +from ohmg.loc_insurancemaps.tasks import load_docs_as_task +from ohmg.frontend.context_processors import user_info_from_request + +logger = logging.getLogger(__name__) + + +class ItemView(View): + + def get(self, request, volumeid): + + volume = get_object_or_404(Volume, pk=volumeid) + volume_json = volume.serialize(include_session_info=True) + + context_dict = { + "svelte_params": { + "TITILER_HOST": settings.TITILER_HOST, + "VOLUME": volume_json, + "CSRFTOKEN": csrf.get_token(request), + "USER": user_info_from_request(request), + "MAPBOX_API_KEY": settings.MAPBOX_API_TOKEN, + } + } + return render( + request, + "content/item.html", + context=context_dict + ) + + def post(self, request, volumeid): + + body = json.loads(request.body) + operation = body.get("operation", None) + + if operation == "initialize": + volume = Volume.objects.get(pk=volumeid) + if volume.loaded_by is None: + volume.loaded_by = request.user + volume.load_date = datetime.now() + volume.save(update_fields=["loaded_by", "load_date"]) + load_docs_as_task.delay(volumeid) + volume_json = volume.serialize(include_session_info=True) + volume_json["status"] = "initializing..." + + return JsonResponse(volume_json) + + elif operation == "set-index-layers": + + volume = Volume.objects.get(pk=volumeid) + + lcat_lookup = body.get("layerCategoryLookup", {}) + + for cat in volume.sorted_layers: + volume.sorted_layers[cat] = [k for k, v in lcat_lookup.items() if v == cat] + + volume.save(update_fields=["sorted_layers"]) + volume_json = volume.serialize(include_session_info=True) + return JsonResponse(volume_json) + + elif operation == "refresh": + volume = Volume.objects.get(pk=volumeid) + volume_json = volume.serialize(include_session_info=True) + return JsonResponse(volume_json) + + elif operation == "refresh-lookups": + volume = Volume.objects.get(pk=volumeid) + volume.refresh_lookups() + volume_json = volume.serialize(include_session_info=True) + return JsonResponse(volume_json) + +class VirtualResourceView(View): + + def get(self, request, pk): + + resource = get_object_or_404(ItemBase, pk=pk) + if resource.type == 'document': + resource = Document.objects.get(pk=pk) + elif resource.type == 'layer': + resource = Layer.objects.get(pk=pk) + + split_summary = resource.get_split_summary() + georeference_summary = resource.get_georeference_summary() + resource_json = resource.serialize() + + volume = find_volume(resource) + volume_json = None + if volume is not None: + volume_json = volume.serialize() + + return render( + request, + "content/resource.html", + context={ + 'resource_params': { + 'REFRESH_URL': None, + 'RESOURCE': resource_json, + 'VOLUME': volume_json, + 'CSRFTOKEN': csrf.get_token(request), + "USER": user_info_from_request(request), + "SPLIT_SUMMARY": split_summary, + "GEOREFERENCE_SUMMARY": georeference_summary, + "MAPBOX_API_KEY": settings.MAPBOX_API_TOKEN, + "OHMG_API_KEY": settings.OHMG_API_KEY, + "SESSION_API_URL": reverse("api-beta:session_list"), + "TITILER_HOST": settings.TITILER_HOST, + } + } + ) diff --git a/ohmg/frontend/context_processors.py b/ohmg/frontend/context_processors.py index d5390e1b..a23f4651 100644 --- a/ohmg/frontend/context_processors.py +++ b/ohmg/frontend/context_processors.py @@ -1,31 +1,41 @@ from django.conf import settings from django.contrib.sites.models import Site -from ohmg.utils import full_reverse +from django.middleware import csrf -def loc_info(request): +from ohmg.accounts.schemas import UserSchema + +def user_info_from_request(request): + """ Return a set of info for the current user in the request. """ try: user = request.user except AttributeError: user = None if user and user.is_authenticated: - user_info = { - 'is_authenticated': True, - 'name': user.username, - 'profile': full_reverse("profile_detail", args=(user.username, )), - } + user_info = UserSchema.from_orm(user).dict() + user_info['is_authenticated'] = True + user_info['is_staff'] = user.is_staff else: user_info = { - 'is_authenticated': False + 'is_authenticated': False, + 'is_staff': False, } + return user_info + +def navbar_footer_params(request): + """ Build the params passed to the Navbar and Footer Svelte components.""" + return { 'navbar_params': { - 'USER': user_info - } + 'USER': user_info_from_request(request), + 'CSRFTOKEN': csrf.get_token(request) + }, + 'footer_params': {}, } -def general(request): - """ neifnef """ +def site_info(request): + """ Return site name, build number, etc. """ + site = Site.objects.get_current() return { 'SITE_NAME': site.name, diff --git a/ohmg/frontend/svelte/src/lib/FireInsuranceMaps.svelte b/ohmg/frontend/pages/about-sanborn-maps.md similarity index 95% rename from ohmg/frontend/svelte/src/lib/FireInsuranceMaps.svelte rename to ohmg/frontend/pages/about-sanborn-maps.md index 908f8d2f..e48f36b8 100644 --- a/ohmg/frontend/svelte/src/lib/FireInsuranceMaps.svelte +++ b/ohmg/frontend/pages/about-sanborn-maps.md @@ -1,7 +1,9 @@ - - - diff --git a/ohmg/frontend/svelte/src/lib/About.svelte b/ohmg/frontend/pages/about.md similarity index 95% rename from ohmg/frontend/svelte/src/lib/About.svelte rename to ohmg/frontend/pages/about.md index 0fed88cc..775cc93d 100644 --- a/ohmg/frontend/svelte/src/lib/About.svelte +++ b/ohmg/frontend/pages/about.md @@ -1,7 +1,8 @@ - - - diff --git a/ohmg/frontend/svelte/src/lib/Contact.svelte b/ohmg/frontend/pages/contact.md similarity index 51% rename from ohmg/frontend/svelte/src/lib/Contact.svelte rename to ohmg/frontend/pages/contact.md index be694c42..ee682d08 100644 --- a/ohmg/frontend/svelte/src/lib/Contact.svelte +++ b/ohmg/frontend/pages/contact.md @@ -1,14 +1,8 @@ - - - diff --git a/ohmg/frontend/svelte/src/lib/FAQ.svelte b/ohmg/frontend/pages/faq.md similarity index 95% rename from ohmg/frontend/svelte/src/lib/FAQ.svelte rename to ohmg/frontend/pages/faq.md index 8534c654..3cf80c0d 100644 --- a/ohmg/frontend/svelte/src/lib/FAQ.svelte +++ b/ohmg/frontend/pages/faq.md @@ -1,7 +1,8 @@ - - - diff --git a/ohmg/frontend/svelte/src/lib/GettingStarted.svelte b/ohmg/frontend/pages/getting-started.md similarity index 56% rename from ohmg/frontend/svelte/src/lib/GettingStarted.svelte rename to ohmg/frontend/pages/getting-started.md index 08db9a46..775b4f4a 100644 --- a/ohmg/frontend/svelte/src/lib/GettingStarted.svelte +++ b/ohmg/frontend/pages/getting-started.md @@ -1,8 +1,9 @@ - - -
- - -

Collaborations

-
- -
- OHM is an OpenStreetMap-inspired project, where contributors can add historical features from anywhere in the world. Any georeferenced historical maps on OldInsuranceMaps.net can be easily integrated as basemaps in the OHM editor, so that features can be digitized directly from them. -
-
-
- - diff --git a/ohmg/frontend/static/css/icons.css b/ohmg/frontend/static/css/icons.css deleted file mode 100644 index e466b587..00000000 --- a/ohmg/frontend/static/css/icons.css +++ /dev/null @@ -1,123 +0,0 @@ -:root { - --volume-svg: url(../icons/noun_UprightBook_2089467.svg); - --volume2-svg: url(../icons/noun-book-3124501-FFFFFF.svg); - --document-svg: url(../icons/noun_Scroll_2592600.svg); - --layer-svg: url(../icons/noun_Layer_2583171.svg); - --webmap-svg: url(../icons/noun_FoldedMap_2592599.svg); - --pinmap-svg: url(../icons/noun_pinmap_1832932.svg); - --user-svg: url(../icons/noun_User_1236015.svg); - --volume-size: 65px; - --document-size: 70px; - --layer-size: 75px; - --webmap-size: 70px; - --pinmap-size: 70px; - --user-size: 50px; -} - -.i-volume { - mask-image: var(--volume2-svg); - -webkit-mask-image: var(--volume2-svg); - display: inline-block; - background: black; - mask-size: cover; - -webkit-mask-size: cover; -} -.i-volume-lg{ - width: var(--volume-size); - height: var(--volume-size); -} -.i-volume-sm { - width: calc(var(--volume-size)*.55); - height: calc(var(--volume-size)*.55); -} - -.i-document { - display: inline-block; - background: black; - mask-size: cover; - -webkit-mask-size: cover; - mask-image: var(--document-svg); - -webkit-mask-image: var(--document-svg); -} -.i-document-lg { - width: var(--document-size); - height: var(--document-size); -} -.i-document-sm { - width: calc(var(--document-size)*.55); - height: calc(var(--document-size)*.55); -} - -.i-layer { - display: inline-block; - background: black; - mask-size: cover; - -webkit-mask-size: cover; - mask-image: var(--layer-svg); - -webkit-mask-image: var(--layer-svg); -} -.i-layer-lg { - width: var(--layer-size); - height: var(--layer-size); -} -.i-layer-sm { - width: calc(var(--layer-size)*.55); - height: calc(var(--layer-size)*.55); -} - -.i-webmap { - display: inline-block; - background: black; - mask-size: cover; - -webkit-mask-size: cover; - mask-image: var(--webmap-svg); - -webkit-mask-image: var(--webmap-svg); -} -.i-webmap-lg { - width: var(--webmap-size); - height: var(--webmap-size); -} -.i-webmap-sm { - width: calc(var(--webmap-size)*.55); - height: calc(var(--webmap-size)*.55); -} - -.i-pinmap { - display: inline-block; - background: black; - mask-size: cover; - -webkit-mask-size: cover; - mask-image: var(--pinmap-svg); - -webkit-mask-image: var(--pinmap-svg); -} -.i-pinmap-lg { - width: var(--pinmap-size); - height: var(--pinmap-size); -} -.i-pinmap-sm { - width: calc(var(--pinmap-size)*.55); - height: calc(var(--pinmap-size)*.55); -} - -.i-user { - display: inline-block; - background: black; - mask-size: cover; - -webkit-mask-size: cover; - mask-image: var(--user-svg); - -webkit-mask-image: var(--user-svg); -} -.i-user-lg { - width: var(--user-size); - height: var(--user-size); -} -.i-user-sm { - width: calc(var(--user-size)*.55); - height: calc(var(--user-size)*.55); -} -.imi { - display: inline-block; - background: black; - mask-size: cover; - -webkit-mask-size: cover; -} \ No newline at end of file diff --git a/ohmg/frontend/static/css/site_base.css b/ohmg/frontend/static/css/site_base.css index 104efae3..abb6ef59 100644 --- a/ohmg/frontend/static/css/site_base.css +++ b/ohmg/frontend/static/css/site_base.css @@ -32,13 +32,12 @@ img { } table { - border-collapse: collapse; border-spacing: 0; } pre { display: block; - padding: 10.5px; + padding: 5px; margin: 0 0 11px; font-size: 15px; line-height: 1.42857143; @@ -63,29 +62,29 @@ code, kbd, pre, samp { } h1 { - font-size: 2.25em; + font-size: 2em; } h2 { - font-size: 2em; + font-size: 1.6em; } h3 { - font-size: 1.6em; + font-size: 1.4em; } h4 { - font-size: 1.25em; + font-size: 1.15em; } h5 { - font-size: 1.15em; + font-size: 1.1em; } h6 { - font-size: 1.1em; + font-size: 1.05em; } h1, h2, h3, h4, h5, h6 { font-weight: 400; line-height: 1.1; } h1, h2, h3 { - margin-top: 22px; + margin-top: 18px; margin-bottom: 11px; } h4, h5, h6 { @@ -130,11 +129,21 @@ a { color: #2c689c; text-decoration: none; } +a.white { + color: white; +} +a.zoom-in { + cursor: zoom-in; +} a:hover { text-decoration: underline; } +a:focus { + text-decoration: underline; +} + a.button { text-transform: none; } @@ -488,4 +497,19 @@ footer a:hover { } .alert-danger .alert-link { color: #843534; + } + + .ffs { + position: fixed !important; + width: 100%; + top: 60px; + height: calc(100vh - 60px) !important; + left: 0; + } + + ul.errorlist { + color: #db0606; + list-style: none; + padding: 0; + font-style: italic; } \ No newline at end of file diff --git a/ohmg/frontend/static/icons/noun-camera-858458.svg b/ohmg/frontend/static/icons/noun-camera-858458.svg new file mode 100644 index 00000000..231cd510 --- /dev/null +++ b/ohmg/frontend/static/icons/noun-camera-858458.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ohmg/frontend/static/icons/noun-compass-867471.svg b/ohmg/frontend/static/icons/noun-compass-867471.svg new file mode 100644 index 00000000..a3139fe0 --- /dev/null +++ b/ohmg/frontend/static/icons/noun-compass-867471.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ohmg/frontend/static/icons/noun-house-2523121-FFFFFF.png b/ohmg/frontend/static/icons/noun-house-2523121-FFFFFF.png new file mode 100644 index 00000000..15f70540 Binary files /dev/null and b/ohmg/frontend/static/icons/noun-house-2523121-FFFFFF.png differ diff --git a/ohmg/frontend/static/icons/noun-magnifier-858462.svg b/ohmg/frontend/static/icons/noun-magnifier-858462.svg new file mode 100644 index 00000000..0a060dd0 --- /dev/null +++ b/ohmg/frontend/static/icons/noun-magnifier-858462.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ohmg/frontend/static/icons/noun-map-pin-858464.svg b/ohmg/frontend/static/icons/noun-map-pin-858464.svg new file mode 100644 index 00000000..a06ea4e9 --- /dev/null +++ b/ohmg/frontend/static/icons/noun-map-pin-858464.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ohmg/frontend/svelte/package.json b/ohmg/frontend/svelte/package.json index 8e412410..e5aa116b 100644 --- a/ohmg/frontend/svelte/package.json +++ b/ohmg/frontend/svelte/package.json @@ -22,6 +22,7 @@ }, "dependencies": { "@petamoriken/float16": "3.4.7", + "@rollup/plugin-alias": "^5.1.0", "ol": "^6.15.1", "ol-ext": "^3.2.28", "ol-hashed": "^2.1.0", diff --git a/ohmg/frontend/svelte/pnpm-lock.yaml b/ohmg/frontend/svelte/pnpm-lock.yaml index c91dd28c..f75607c8 100644 --- a/ohmg/frontend/svelte/pnpm-lock.yaml +++ b/ohmg/frontend/svelte/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: '@petamoriken/float16': specifier: 3.4.7 version: 3.4.7 + '@rollup/plugin-alias': + specifier: ^5.1.0 + version: 5.1.0(rollup@2.79.1) ol: specifier: ^6.15.1 version: 6.15.1 @@ -441,6 +444,19 @@ packages: resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==} dev: false + /@rollup/plugin-alias@5.1.0(rollup@2.79.1): + resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + rollup: 2.79.1 + slash: 4.0.0 + dev: false + /@rollup/plugin-commonjs@16.0.0(rollup@2.79.1): resolution: {integrity: sha512-LuNyypCP3msCGVQJ7ki8PqYdpjfEkE/xtFa5DqlF+7IBD0JsfMZ87C58heSwIMint58sAUZbt3ITqOmdQv/dXw==} engines: {node: '>= 8.0.0'} @@ -985,7 +1001,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: true optional: true /function-bind@1.1.2: @@ -1666,7 +1681,6 @@ packages: hasBin: true optionalDependencies: fsevents: 2.3.3 - dev: true /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -1749,6 +1763,11 @@ packages: totalist: 1.1.0 dev: false + /slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: false + /sort-asc@0.1.0: resolution: {integrity: sha512-jBgdDd+rQ+HkZF2/OHCmace5dvpos/aWQpcxuyRs9QUbPRnkEJmYVo81PIGpjIdpOcsnJ4rGjStfDHsbn+UVyw==} engines: {node: '>=0.10.0'} diff --git a/ohmg/frontend/svelte/rollup.config.js b/ohmg/frontend/svelte/rollup.config.js index 36db03a2..8232262d 100644 --- a/ohmg/frontend/svelte/rollup.config.js +++ b/ohmg/frontend/svelte/rollup.config.js @@ -4,6 +4,8 @@ import resolve from '@rollup/plugin-node-resolve'; import livereload from 'rollup-plugin-livereload'; import { terser } from 'rollup-plugin-terser'; import css from 'rollup-plugin-css-only'; +import alias from '@rollup/plugin-alias'; +import path from "path"; const production = !process.env.ROLLUP_WATCH; @@ -30,7 +32,7 @@ function serve() { function componentExportDetails(componentName) { return { - input: `src/entry/${componentName.toLowerCase()}.js`, + input: `src/${componentName.toLowerCase()}.js`, output: { sourcemap: true, format: 'iife', @@ -39,6 +41,28 @@ function componentExportDetails(componentName) { inlineDynamicImports: true, }, plugins: [ + alias({ + /** + * For custom files extension you might want to add "customerResolver" + * https://github.com/rollup/plugins/tree/master/packages/alias#custom-resolvers + * + * By doing that this plugin can read different kind of files. + */ + entries: [{ + find: "@src", + replacement: path.resolve(__dirname, "src"), + }, + { + find: "@helpers", + replacement: path.resolve(__dirname, "src/helpers"), + }, + { + find: "@components", + replacement: path.resolve(__dirname, "src/lib/components"), + }, + ], + }), + svelte({ compilerOptions: { // enable run-time checks when not in production @@ -90,8 +114,8 @@ function componentExportDetails(componentName) { let exportable = []; -// Add exportables here. These must match a lowercase file in ./entry -// e.g. ./entry/main.js +// Add exportables here. These must match a lowercase file in ./src +// e.g. ./src/main.js [ "Index", "Footer", @@ -100,7 +124,7 @@ let exportable = []; "Resource", "Split", "Viewer", - "Volume", + "Item", ].forEach((d) => exportable.push(componentExportDetails(d))); export default exportable; diff --git a/ohmg/frontend/svelte/src/css/interface.css b/ohmg/frontend/svelte/src/css/interface.css index 82ad8d8f..6760ce9c 100644 --- a/ohmg/frontend/svelte/src/css/interface.css +++ b/ohmg/frontend/svelte/src/css/interface.css @@ -39,18 +39,6 @@ color: grey; } -.signin-reminder { - background: #e6e6e6; - text-align: center; - padding: 5px; - margin: 5px; - border-radius: 4px; -} - -.signin-reminder p { - margin: 0px; -} - .interface-mask { height: 597px; /* 600 - 2 * 1.5px borders on the main component */ width: 100%; @@ -175,7 +163,7 @@ } table.tablesort { - width:100%; + width: 100%; } th.sortable, td { diff --git a/ohmg/frontend/svelte/src/css/modal.css b/ohmg/frontend/svelte/src/css/modal.css deleted file mode 100644 index fa4a4368..00000000 --- a/ohmg/frontend/svelte/src/css/modal.css +++ /dev/null @@ -1,81 +0,0 @@ -#topModal { - visibility: hidden; - z-index: 9999; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: #4448; - display: flex; - align-items: center; - justify-content: center; -} -#modal { - position: relative; - border-radius: 6px; - background: #123B4F; - color: white; - /* border: 1px solid #000; */ - filter: drop-shadow(5px 5px 5px #555); - padding: 1em; - margin: 1em; - max-height: 100vh; -} -#modal img { - max-height: calc(100vh - 2em); -} - -/* mimic the .container widths */ -@media (min-width: 768px) { - #modal { - max-width: 750px; - } -} -@media (min-width: 992px) { - #modal { - max-width: 970px; - } -} -@media (min-width: 1200px) { - #modal { - max-width: 1170px; - } -} - -.visible { - visibility: visible !important; -} - -#close { - position: absolute; - top:-12px; - right:-12px; - width:24px; - height:24px; - cursor: pointer; - fill:#F44; - /* transition: transform 0.3s; */ -} - -#close:hover { - /* transform: scale(2); */ -} - -#close line { - stroke:#FFF; - stroke-width:2; -} -#modal-content { - max-width: calc(100vw - 20px); - max-height: calc(100vh - 20px); - overflow: auto; -} -#modal-content a { - text-decoration: underline; - color: white; - font-weight: bolder; -} -#modal-content button { - color: black; -} \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/css/shared.css b/ohmg/frontend/svelte/src/css/shared.css index e3e7cc78..f846047c 100644 --- a/ohmg/frontend/svelte/src/css/shared.css +++ b/ohmg/frontend/svelte/src/css/shared.css @@ -7,23 +7,15 @@ h1, h2, h3, h4, h5, h6 { scroll-margin-top: 65px } -.signin-reminder { - background: #e6e6e6; - text-align: center; - padding: 5px; - margin: 5px; -} - -.signin-reminder p { - margin: 0px; -} - table.tablesort { width:100%; + border: 1px solid grey; + border-radius: 4px; } th.sortable, td { padding: 5px; + white-space: nowrap; } thead tr { diff --git a/ohmg/frontend/svelte/src/entry/volume.js b/ohmg/frontend/svelte/src/entry/volume.js deleted file mode 100644 index 6023eee0..00000000 --- a/ohmg/frontend/svelte/src/entry/volume.js +++ /dev/null @@ -1,12 +0,0 @@ -import '../css/shared.css'; -import '../css/interface.css'; - -import Volume from '../lib/Volume.svelte'; -import '../css/ol-overrides.css' - -const volume = new Volume({ - target: document.getElementById("volume-target"), - props: JSON.parse(document.getElementById("volume-props").textContent), -}); - -export default volume; \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/entry/footer.js b/ohmg/frontend/svelte/src/footer.js similarity index 76% rename from ohmg/frontend/svelte/src/entry/footer.js rename to ohmg/frontend/svelte/src/footer.js index 78050a71..2bd54f9d 100644 --- a/ohmg/frontend/svelte/src/entry/footer.js +++ b/ohmg/frontend/svelte/src/footer.js @@ -1,4 +1,4 @@ -import Footer from '../lib/Footer.svelte'; +import Footer from '@components/layout/Footer.svelte'; const footer = new Footer({ target: document.getElementById("footer-target"), diff --git a/ohmg/frontend/svelte/src/entry/georeference.js b/ohmg/frontend/svelte/src/georeference.js similarity index 59% rename from ohmg/frontend/svelte/src/entry/georeference.js rename to ohmg/frontend/svelte/src/georeference.js index 4cb26eb4..37c150ac 100644 --- a/ohmg/frontend/svelte/src/entry/georeference.js +++ b/ohmg/frontend/svelte/src/georeference.js @@ -1,6 +1,6 @@ -import '../css/interface.css'; -import Georeference from '../lib/Georeference.svelte'; -import '../css/ol-overrides.css' +import '@src/css/interface.css'; +import Georeference from '@src/lib/pages/Georeference.svelte'; +import '@src/css/ol-overrides.css' const app = new Georeference({ target: document.getElementById("georeference-target"), diff --git a/ohmg/frontend/svelte/src/js/ol-styles.js b/ohmg/frontend/svelte/src/helpers/ol-styles.js similarity index 100% rename from ohmg/frontend/svelte/src/js/ol-styles.js rename to ohmg/frontend/svelte/src/helpers/ol-styles.js diff --git a/ohmg/frontend/svelte/src/js/utils.js b/ohmg/frontend/svelte/src/helpers/utils.js similarity index 93% rename from ohmg/frontend/svelte/src/js/utils.js rename to ohmg/frontend/svelte/src/helpers/utils.js index 3dbd0aca..62aa9e5b 100644 --- a/ohmg/frontend/svelte/src/js/utils.js +++ b/ohmg/frontend/svelte/src/helpers/utils.js @@ -25,24 +25,6 @@ import MapboxVector from 'ol/layer/MapboxVector'; import Crop from 'ol-ext/filter/Crop'; import { extendFlatCoordinates } from 'ol/extent'; -export function toggleFullscreen (elementId) { - // https://www.w3schools.com/howto/howto_js_fullscreen.asp - const elem = document.getElementById(elementId) - if (document.fullscreenElement == null) { - if (elem.requestFullscreen) { - elem.requestFullscreen(); - } else if (elem.webkitRequestFullscreen) { /* Safari */ - elem.webkitRequestFullscreen(); - } else if (elem.msRequestFullscreen) { /* IE11 */ - elem.msRequestFullscreen(); - } - return true - } else { - document.exitFullscreen(); - return false - } -} - export function makeTitilerXYZUrl (options) { // options must be an object with the following properties: // { @@ -273,4 +255,11 @@ export function removeRotateCenter (layer) { // just inherit color I think. export const iconProps = { weight: 'bold', +} + +export function setMapExtent(map, extent4326) { + if (map) { + const extent3857 = transformExtent(extent4326, "EPSG:4326", "EPSG:3857"); + map.getView().fit(extent3857); + } } \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/entry/index.js b/ohmg/frontend/svelte/src/index.js similarity index 77% rename from ohmg/frontend/svelte/src/entry/index.js rename to ohmg/frontend/svelte/src/index.js index bce7a0ef..d96aed19 100644 --- a/ohmg/frontend/svelte/src/entry/index.js +++ b/ohmg/frontend/svelte/src/index.js @@ -1,4 +1,4 @@ -import Index from '../lib/Index.svelte'; +import Index from '@src/lib/pages/Index.svelte'; const app = new Index({ target: document.getElementById("index-target"), diff --git a/ohmg/frontend/svelte/src/item.js b/ohmg/frontend/svelte/src/item.js new file mode 100644 index 00000000..51fc8f64 --- /dev/null +++ b/ohmg/frontend/svelte/src/item.js @@ -0,0 +1,12 @@ +import '@src/css/shared.css'; +import '@src/css/interface.css'; + +import Item from '@src/lib/components/overviews/Item.svelte'; +import '@src/css/ol-overrides.css' + +const item = new Item({ + target: document.getElementById("item-target"), + props: JSON.parse(document.getElementById("item-props").textContent), +}); + +export default item; \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/Activity.svelte b/ohmg/frontend/svelte/src/lib/Activity.svelte deleted file mode 100644 index 97db8755..00000000 --- a/ohmg/frontend/svelte/src/lib/Activity.svelte +++ /dev/null @@ -1,20 +0,0 @@ - -
- - -
- - diff --git a/ohmg/frontend/svelte/src/lib/Footer.svelte b/ohmg/frontend/svelte/src/lib/Footer.svelte deleted file mode 100644 index c7bd5df4..00000000 --- a/ohmg/frontend/svelte/src/lib/Footer.svelte +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - diff --git a/ohmg/frontend/svelte/src/lib/Navbar.svelte b/ohmg/frontend/svelte/src/lib/Navbar.svelte deleted file mode 100644 index f4cfa3c9..00000000 --- a/ohmg/frontend/svelte/src/lib/Navbar.svelte +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - diff --git a/ohmg/frontend/svelte/src/lib/Place.svelte b/ohmg/frontend/svelte/src/lib/Place.svelte deleted file mode 100644 index 53f04298..00000000 --- a/ohmg/frontend/svelte/src/lib/Place.svelte +++ /dev/null @@ -1,75 +0,0 @@ - - -
- {#each PLACE.breadcrumbs as bc, n} - {#if n != PLACE.breadcrumbs.length-1} → {/if} - {/each} -
-
-
-

Locales

- {#if PLACE.descendants.length > 0} -
    - {#each PLACE.descendants as d} -
  • - -
  • - {/each} -
- {:else} -

---

- {/if} -
-
-

Maps

- {#if PLACE.volumes.length > 0} - - {:else} -

---

- {/if} -
-
- diff --git a/ohmg/frontend/svelte/src/lib/Resource.svelte b/ohmg/frontend/svelte/src/lib/Resource.svelte deleted file mode 100644 index 8a1123ad..00000000 --- a/ohmg/frontend/svelte/src/lib/Resource.svelte +++ /dev/null @@ -1,575 +0,0 @@ - - - -
- -
-
- {#each reinitMap as key (key)} - {#if RESOURCE.type == "document"} - - {:else} - - {/if} - {/each} -
- -
-
-

Session History

- -
-
-
- - diff --git a/ohmg/frontend/svelte/src/lib/Volume.svelte b/ohmg/frontend/svelte/src/lib/Volume.svelte deleted file mode 100644 index c17ddd53..00000000 --- a/ohmg/frontend/svelte/src/lib/Volume.svelte +++ /dev/null @@ -1,729 +0,0 @@ - - - - {#each reinitMap2 as key (key)} - - {/each} - - - {#each reinitMap3 as key (key)} - - {/each} - - -

The Mosaic Preview shows progress toward a full mosaic of this item's content—as documents are georeferenced, they will automatically appear here. You can also view this mosaic alongside all other mosaics for this locale: {VOLUME.locale.display_name}

-
- -

The Georeferencing Overview provides a per-document summary and access point to the entire georeferencing process for this item's content.

-
- -

Each document in the Unprepared section must be evaluated individually, and, if it contains more than one mapped area, split into separate pieces.

-
- -

Content in the Prepared section is ready to be georeferenced. You can also decide here if a particular document should be moved to the Non-map Content section, for example if it is a title page or text index (this designation can be easily reversed).

-
- -

The Georeferenced section holds all content that has been spatially rectified, though you can still edit the control points for any layer whose georeferencing should be improved. Use the Classify Layers button to sort layers into different categories, if applicable. For example, if a Key Map is present, classify it here so other interfaces will treat it appropriately.

-
- -

The MultiMask is a mechanism for trimming the margins from every layer in a way that guarantees a seamless mosaic across this item's content.

-

How to create a MultiMask

-
    -
  • Use to start a mask for a particular layer.
  • -
  • Use to delete an existing mask.
  • -
  • Use to save your work (do this often!).
  • -
  • Use to discard all changes since the last save.
  • -
-

Important Notes

-
    -
  • You must be signed in to save your work, so don't get started before you are signed in!
  • -
  • The vertices of every adjacent mask should be snapped together
  • -
  • You can drag existing vertices to snap them to others, but this is sometimes "sticky" and takes a couple of tries.
  • -
  • If a mosaic is generated for this item, only layers that have been masked will be included in the mosaic.
  • -
-
- -

The Non-Map Content section holds documents (or document fragments) that are not maps, like a title page or text index.

-
- -

-
-
- -
-

- {#each OTHER_VOLUMES as link, n} - {#if n != 0} • {/if} - {#if link.url}{link.display}{:else}{link.display}{/if} - {/each} - -

-
-
-
- - -
- {#if showMap} -
- - {#each reinitMap as key (key)} - - {/each} -
- {/if} -
-
-
- - {#if refreshingLookups} -
- {/if} - -
-
-
-
- {#if VOLUME.sheet_ct.loaded < VOLUME.sheet_ct.total && USER_TYPE != 'anonymous' && !sheetsLoading} - - {/if} - - {#if sheetsLoading} - Loading sheet {VOLUME.sheet_ct.loaded}/{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 USER_TYPE != "anonymous"} - - {/if} - -
-
- {#if USER_TYPE == 'anonymous' } - - {/if} -
- - {#if showUnprepared} -
-
- {#each VOLUME.items.unprepared as document} -
- - -
- {#if document.lock_enabled} -
    -
  • preparation in progress.
  • -
  • user: {document.lock_details.user.name}
  • -
- {:else} - - {/if} -
-
- {/each} -
-
- {/if} -
-
- - {#if showPrepared} -
-
- {#each VOLUME.items.prepared as document} -
- - -
- {#if document.lock_enabled} -
    -
  • georeferencing in progress...
  • -
  • {document.lock_details.user.name}
  • -
- {:else} -
    -
  • georeference →
  • -
  • -
- {/if} -
-
- {/each} -
-
- {/if} -
-
-
- - -
- {#if showGeoreferenced} -
-
- {#if VOLUME.items.layers.length > 0 && !settingKeyMapLayer} - - {/if} - {#if settingKeyMapLayer} - - - {/if} -
-
- {#each VOLUME.items.layers as layer} -
- - - - -
- {#if layer.lock && layer.lock.enabled} -
    -
  • session in progress...
  • -
  • {layer.lock.username}
  • -
- {:else} - - {/if} - {#if settingKeyMapLayer} - - {/if} -
-
- {/each} -
- -
- {/if} -
-
-
- - -
- {#if showMultimask} -
- -
- {/if} -
-
-
- - -
- {#if showNonmaps} -
-
- {#each VOLUME.items.nonmaps as nonmap} -
- - - {nonmap.title} - -
-
    -
  • -
-
-
- {/each} -
-
- {/if} -
-
-
- -
-
- -
- {#if showDownload} -
-
-

- Only layers that have been trimmed in the Multimask will appear in the mosaic. You can access untrimmed layers individually through the Georeferenced section above. If you appreciate these resources, please consider supporting this project. -

-
-
-

XYZ Tiles URL

- {#if !VOLUME.urls.mosaic_json} -

- A mosaic endpoint has not yet been generated for this volume. -

- {:else} -
{mosaicUrl}
-

Use this URL in: - Leaflet, - OpenLayers, - Mapbox/MapLibre GL JS, - QGIS, and - ArcGIS. -
Open in the Open Historical Map editor . -

- {/if} -
-
-

GeoTIFF mosaic downloads of this entire volume are available upon request.

-
-
- {/if} -
-
- -
-

- {VOLUME.sessions.prep_ct} sheet{#if VOLUME.sessions.prep_ct != 1}s{/if} prepared{#if VOLUME.sessions.prep_ct > 0} by - {#each VOLUME.sessions.prep_contributors as c, n}{c.name} ({c.ct}){#if n != VOLUME.sessions.prep_contributors.length-1}, {/if}{/each}{/if} -
- {VOLUME.sessions.georef_ct} georeferencing session{#if VOLUME.sessions.georef_ct != 1}s{/if}{#if VOLUME.sessions.georef_ct > 0} by - {#each VOLUME.sessions.georef_contributors as c, n}{c.name} ({c.ct}){#if n != VOLUME.sessions.georef_contributors.length-1}, {/if}{/each}{/if} -

-

Credit Line: Library of Congress, Geography and Map Division, Sanborn Maps Collection. - View item on loc.gov

-
-
-
-
- diff --git a/ohmg/frontend/svelte/src/lib/components/LatestAdditions.svelte b/ohmg/frontend/svelte/src/lib/components/LatestAdditions.svelte deleted file mode 100644 index e8b73654..00000000 --- a/ohmg/frontend/svelte/src/lib/components/LatestAdditions.svelte +++ /dev/null @@ -1,47 +0,0 @@ - -
- {#if loadingItems} -
- {:else} - {#each latestItems as v} -
- {v.title} ({v.sheet_ct}) — - {v.loaded_by.username} — - {v.load_date} -
- {/each} - {/if} -
- diff --git a/ohmg/frontend/svelte/src/lib/components/PlaceSelect.svelte b/ohmg/frontend/svelte/src/lib/components/PlaceSelect.svelte deleted file mode 100644 index 4c7c9a6d..00000000 --- a/ohmg/frontend/svelte/src/lib/components/PlaceSelect.svelte +++ /dev/null @@ -1,42 +0,0 @@ - - -
- {#if editing} -

editing

- {:else} - {#if VOLUME.locale} - {#each breadCrumbs as bc, n} - {bc.name}{#if n != breadCrumbs.length-1} → {/if} - {/each} - {:else} -

No locale defined.

- {/if} - {/if} - -
- - diff --git a/ohmg/frontend/svelte/src/lib/components/Places.svelte b/ohmg/frontend/svelte/src/lib/components/Places.svelte deleted file mode 100644 index 55fde6b6..00000000 --- a/ohmg/frontend/svelte/src/lib/components/Places.svelte +++ /dev/null @@ -1,76 +0,0 @@ - - -
- -
-
- {#if loading} -
-
-
- {:else if filtered_places.length === 0} -

No places found...

- {:else} - - - Place - Volumes available - - - {p.name} - {#each p.items as v, i}{v.year}{#if i < p.items.length-1}, {/if}{/each} - - - {/if} -
- - diff --git a/ohmg/frontend/svelte/src/lib/components/TitleBar.svelte b/ohmg/frontend/svelte/src/lib/components/TitleBar.svelte deleted file mode 100644 index 635cfb24..00000000 --- a/ohmg/frontend/svelte/src/lib/components/TitleBar.svelte +++ /dev/null @@ -1,86 +0,0 @@ - - - -
-
- {#if IMG_URL} - {TITLE} - {/if} -

{ TITLE }

-
- {#if ICON_LINKS.length > 0} -
- {#each ICON_LINKS as link} - {#if link.visible} - - - - {/if} - {/each} -
- {/if} - {#if SIDE_LINKS.length > 0} - - {/if} -
-
- - \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/VolumePreviewMap.svelte b/ohmg/frontend/svelte/src/lib/components/VolumePreviewMap.svelte deleted file mode 100644 index 2e395239..00000000 --- a/ohmg/frontend/svelte/src/lib/components/VolumePreviewMap.svelte +++ /dev/null @@ -1,236 +0,0 @@ - - - {keyImgCaption} - - -
-
-
-
-
-
- - - -
-
- -
- Basemap - -
-
- {currentBasemap} -
- -
- Key Map - -
-
- {#if VOLUME.sorted_layers.key_map.length == 0} - no key map set - {:else} - - {/if} -
-
- Main Layers - -
-
- {#if VOLUME.sorted_layers.main.length == 0} - no layers - {:else} - - {/if} -
-
-
-
-
diff --git a/ohmg/frontend/svelte/src/lib/components/base/IconButton.svelte b/ohmg/frontend/svelte/src/lib/components/base/IconButton.svelte new file mode 100644 index 00000000..a8600020 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/base/IconButton.svelte @@ -0,0 +1,153 @@ + + + + + + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/icons/GlobalIconContext.svelte b/ohmg/frontend/svelte/src/lib/components/base/IconContext.svelte similarity index 81% rename from ohmg/frontend/svelte/src/lib/components/icons/GlobalIconContext.svelte rename to ohmg/frontend/svelte/src/lib/components/base/IconContext.svelte index 38365634..bf0cd835 100644 --- a/ohmg/frontend/svelte/src/lib/components/icons/GlobalIconContext.svelte +++ b/ohmg/frontend/svelte/src/lib/components/base/IconContext.svelte @@ -1,4 +1,5 @@ + +{#if external} + + + + + + +{:else} + + + +{/if} + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/Modal.svelte b/ohmg/frontend/svelte/src/lib/components/base/Modal.svelte similarity index 64% rename from ohmg/frontend/svelte/src/lib/components/Modal.svelte rename to ohmg/frontend/svelte/src/lib/components/base/Modal.svelte index e36e0ef6..24191641 100644 --- a/ohmg/frontend/svelte/src/lib/components/Modal.svelte +++ b/ohmg/frontend/svelte/src/lib/components/base/Modal.svelte @@ -13,8 +13,7 @@ import {onDestroy} from 'svelte' import SvelteMarkdown from 'svelte-markdown'; -import '../../css/modal.css'; -import '../../css/ol-overrides.css'; +import '@src/css/ol-overrides.css'; let topDiv let visible=false @@ -87,14 +86,96 @@ onDestroy(()=>{ diff --git a/ohmg/frontend/svelte/src/lib/components/base/OpenModalButton.svelte b/ohmg/frontend/svelte/src/lib/components/base/OpenModalButton.svelte new file mode 100644 index 00000000..f6e87ce5 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/base/OpenModalButton.svelte @@ -0,0 +1,13 @@ + + + {getModal(modalId).open()}} title={title}> + + diff --git a/ohmg/frontend/svelte/src/lib/components/base/SVGButton.svelte b/ohmg/frontend/svelte/src/lib/components/base/SVGButton.svelte new file mode 100644 index 00000000..43e09c5e --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/base/SVGButton.svelte @@ -0,0 +1,52 @@ + + + + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/base/SVGIcon.svelte b/ohmg/frontend/svelte/src/lib/components/base/SVGIcon.svelte new file mode 100644 index 00000000..fca05706 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/base/SVGIcon.svelte @@ -0,0 +1,211 @@ + + + + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/buttons/InfoButton.svelte b/ohmg/frontend/svelte/src/lib/components/buttons/InfoButton.svelte deleted file mode 100644 index f7ef7702..00000000 --- a/ohmg/frontend/svelte/src/lib/components/buttons/InfoButton.svelte +++ /dev/null @@ -1,26 +0,0 @@ - - - - - \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/Georeference.svelte b/ohmg/frontend/svelte/src/lib/components/interfaces/Georeferencer.svelte similarity index 93% rename from ohmg/frontend/svelte/src/lib/Georeference.svelte rename to ohmg/frontend/svelte/src/lib/components/interfaces/Georeferencer.svelte index 730dd57d..2192e24a 100644 --- a/ohmg/frontend/svelte/src/lib/Georeference.svelte +++ b/ohmg/frontend/svelte/src/lib/components/interfaces/Georeferencer.svelte @@ -1,12 +1,9 @@ {if (!leaveOkay) {confirmLeave()}}} on:unload={cleanup}/> - -

Create 3 or more ground control points to georeference this document. To create a ground control point, first click on a location in the left panel, then find and click on the corresponding location in right panel. Learn more

+

Create 3 or more ground control points to georeference this document. To create a ground control point, first click on a location in the left panel, then find and click on the corresponding location in right panel. Learn more

This georeferencing session is expiring, and will be cancelled soon.

@@ -944,8 +915,8 @@ const iconLinks = [

Feel free to experiment with the interface, but submit your work you must - sign in or - sign up. + sign in or + sign up.

@@ -965,12 +936,12 @@ const iconLinks = [
diff --git a/ohmg/frontend/svelte/src/lib/components/interfaces/ItemPreviewMap.svelte b/ohmg/frontend/svelte/src/lib/components/interfaces/ItemPreviewMap.svelte new file mode 100644 index 00000000..bd2633a0 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/interfaces/ItemPreviewMap.svelte @@ -0,0 +1,197 @@ + + + + +
+
+
+
+
+
+ {setMapExtent(map, VOLUME.extent)}} /> + + +
+
+
+ Basemap + +
+
+ {currentBasemap} +
+ {#each layerSetList as id} + {#if layerSets[id].layerCt > 0} +
+ {layerSets[id].name} +
+
+
+ + +
+
+ {/if} + {/each} +
+
+
+
diff --git a/ohmg/frontend/svelte/src/lib/components/MapBrowse.svelte b/ohmg/frontend/svelte/src/lib/components/interfaces/MapBrowse.svelte similarity index 99% rename from ohmg/frontend/svelte/src/lib/components/MapBrowse.svelte rename to ohmg/frontend/svelte/src/lib/components/interfaces/MapBrowse.svelte index fd1937ab..4ca194dd 100644 --- a/ohmg/frontend/svelte/src/lib/components/MapBrowse.svelte +++ b/ohmg/frontend/svelte/src/lib/components/interfaces/MapBrowse.svelte @@ -16,7 +16,7 @@ import VectorSource from 'ol/source/Vector'; import TileLayer from 'ol/layer/Tile'; import VectorLayer from 'ol/layer/Vector'; -import Styles from '../../js/ol-styles'; +import Styles from '@helpers/ol-styles'; const styles = new Styles(); export let PLACES_GEOJSON_URL; diff --git a/ohmg/frontend/svelte/src/lib/components/MultiTrim.svelte b/ohmg/frontend/svelte/src/lib/components/interfaces/MultiMask.svelte similarity index 85% rename from ohmg/frontend/svelte/src/lib/components/MultiTrim.svelte rename to ohmg/frontend/svelte/src/lib/components/interfaces/MultiMask.svelte index 7d52e418..9976563f 100644 --- a/ohmg/frontend/svelte/src/lib/components/MultiTrim.svelte +++ b/ohmg/frontend/svelte/src/lib/components/interfaces/MultiMask.svelte @@ -1,15 +1,7 @@ -{#if USER_TYPE == "anonymous"}

Feel free to mess around; you can't save changes unless you are logged in.

{/if}
@@ -426,16 +415,8 @@ function handleFfs(elementId) {
- - + +
@@ -444,9 +425,7 @@ function handleFfs(elementId) {
{#each layerLookupUnmaskedArr as layer}
- + addMask(layer)} />   + layerRemoveMask(layer)} />  
- - + +
@@ -489,14 +462,6 @@ function handleFfs(elementId) { \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/interfaces/buttons/FullExtentButton.svelte b/ohmg/frontend/svelte/src/lib/components/interfaces/buttons/FullExtentButton.svelte new file mode 100644 index 00000000..a678f5c3 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/interfaces/buttons/FullExtentButton.svelte @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/interfaces/buttons/MapboxLogoLink.svelte b/ohmg/frontend/svelte/src/lib/components/interfaces/buttons/MapboxLogoLink.svelte new file mode 100644 index 00000000..b1e3086d --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/interfaces/buttons/MapboxLogoLink.svelte @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/interfaces/buttons/OpenModalButton.svelte b/ohmg/frontend/svelte/src/lib/components/interfaces/buttons/OpenModalButton.svelte new file mode 100644 index 00000000..149e7ca2 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/interfaces/buttons/OpenModalButton.svelte @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/interfaces/modals/LegendModal.svelte b/ohmg/frontend/svelte/src/lib/components/interfaces/modals/LegendModal.svelte new file mode 100644 index 00000000..9d3ef4c5 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/interfaces/modals/LegendModal.svelte @@ -0,0 +1,11 @@ + + + + {legendAlt} + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/layout/Footer.svelte b/ohmg/frontend/svelte/src/lib/components/layout/Footer.svelte new file mode 100644 index 00000000..84f03111 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/layout/Footer.svelte @@ -0,0 +1,119 @@ + + + +
+
+ {#each linkSets as set} +
+

{set.header}

+
    + {#each set.links as link} +
  • {link.title}
  • + {/each} +
+
+ {/each} +
+
+ Copyright © 2024 +
+
+
+ diff --git a/ohmg/frontend/svelte/src/lib/components/MarkdownPage.svelte b/ohmg/frontend/svelte/src/lib/components/layout/MarkdownPage.svelte similarity index 77% rename from ohmg/frontend/svelte/src/lib/components/MarkdownPage.svelte rename to ohmg/frontend/svelte/src/lib/components/layout/MarkdownPage.svelte index 324721fe..d10d273a 100644 --- a/ohmg/frontend/svelte/src/lib/components/MarkdownPage.svelte +++ b/ohmg/frontend/svelte/src/lib/components/layout/MarkdownPage.svelte @@ -1,11 +1,13 @@
- +
- {#if makeToc} + {#if MAKE_TOC}
    {#each headings as heading} -
  • {heading.text}
  • +
  • {heading.text}
  • {/each}
diff --git a/ohmg/frontend/svelte/src/lib/components/layout/NavDropdown.svelte b/ohmg/frontend/svelte/src/lib/components/layout/NavDropdown.svelte new file mode 100644 index 00000000..b0e10836 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/layout/NavDropdown.svelte @@ -0,0 +1,35 @@ + + + + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/layout/Navbar.svelte b/ohmg/frontend/svelte/src/lib/components/layout/Navbar.svelte new file mode 100644 index 00000000..e52e1e1b --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/layout/Navbar.svelte @@ -0,0 +1,218 @@ + + + + + + + diff --git a/ohmg/frontend/svelte/src/lib/components/layout/SigninModal.svelte b/ohmg/frontend/svelte/src/lib/components/layout/SigninModal.svelte new file mode 100644 index 00000000..95ec8ad1 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/layout/SigninModal.svelte @@ -0,0 +1,48 @@ + + + + {#if showForm == "signin"} +

Sign in

+

If you have not yet created an account, then please {showForm = 'signup'}} title="Sign up">sign up first.

+ + {:else if showForm == 'signup'} +

Sign up

+

If you already have an account, please {showForm = 'signin'}} title="Sign in">sign in.

+ + {/if} +
+ + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/layout/SigninReminder.svelte b/ohmg/frontend/svelte/src/lib/components/layout/SigninReminder.svelte new file mode 100644 index 00000000..b33921a1 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/layout/SigninReminder.svelte @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/layout/TitleBar.svelte b/ohmg/frontend/svelte/src/lib/components/layout/TitleBar.svelte new file mode 100644 index 00000000..4d499c78 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/layout/TitleBar.svelte @@ -0,0 +1,61 @@ + + +
+
+ {#if IMG_URL} + {TITLE} + {/if} +

{ TITLE }

+
+ {#if ICON_LINKS.length > 0} +
+ {#each ICON_LINKS as link} + {#if link.visible} + {location.href = link.url}} disabled={!link.enabled} /> + {/if} + {/each} +
+ {/if} + {#if VIEWER_LINK} +
+ {window.open(VIEWER_LINK,'_blank');}}> +
+ {/if} +
+ + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/Volumes.svelte b/ohmg/frontend/svelte/src/lib/components/lists/Items.svelte similarity index 66% rename from ohmg/frontend/svelte/src/lib/components/Volumes.svelte rename to ohmg/frontend/svelte/src/lib/components/lists/Items.svelte index 9c8825e1..d56e1d20 100644 --- a/ohmg/frontend/svelte/src/lib/components/Volumes.svelte +++ b/ohmg/frontend/svelte/src/lib/components/lists/Items.svelte @@ -1,46 +1,54 @@
- + +
{#if loading} @@ -70,7 +79,7 @@ $: updateFilteredList(filterInput) {:else} - Item Title + Title Year Sheets Loaded by @@ -85,11 +94,17 @@ $: updateFilteredList(filterInput) - {v.title} + {v.title} {v.year_vol} {v.sheet_ct} - {v.loaded_by_name} + + {#if v.loaded_by_name != "---" } + {v.loaded_by_name} + {:else} + {v.loaded_by_name} + {/if} + {v.load_date} {v.unprepared_ct} {v.prepared_ct} @@ -118,11 +133,9 @@ $: updateFilteredList(filterInput) diff --git a/ohmg/frontend/svelte/src/lib/Participants.svelte b/ohmg/frontend/svelte/src/lib/components/lists/Participants.svelte similarity index 61% rename from ohmg/frontend/svelte/src/lib/Participants.svelte rename to ohmg/frontend/svelte/src/lib/components/lists/Participants.svelte index 05469580..b7447f12 100644 --- a/ohmg/frontend/svelte/src/lib/Participants.svelte +++ b/ohmg/frontend/svelte/src/lib/components/lists/Participants.svelte @@ -1,50 +1,49 @@ - +
@@ -62,16 +61,16 @@ function toggleList(userId) { {p.username} - + {p.username} - +
{p.load_ct}{#if p.volumes.length > 0} —{/if} {#each p.volumes as v, n} {#if n <= 2} - {v.title}{#if n != p.volumes.length - 1}, {/if} + {v.title}{#if n != p.volumes.length - 1}, {/if} {/if} {/each} {#if p.volumes.length > 3} @@ -82,7 +81,7 @@ function toggleList(userId) {
    {#each p.volumes as v} -
  • {v.title}
  • +
  • {v.title}
  • {/each}
diff --git a/ohmg/frontend/svelte/src/lib/components/lists/Places.svelte b/ohmg/frontend/svelte/src/lib/components/lists/Places.svelte new file mode 100644 index 00000000..9f58c661 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/lists/Places.svelte @@ -0,0 +1,78 @@ + + +
New! Search by place hierarchy →
+
+ +
+
+ {#if loading} +
+
+
+ {:else if filtered_places.length === 0} +

No places found...

+ {:else} + + + Place + Volumes available + + + {p.name} + {#each p.items as v, i}{v.year}{#if i < p.items.length-1}, {/if}{/each} + + + {/if} +
+ + diff --git a/ohmg/frontend/svelte/src/lib/components/SessionList.svelte b/ohmg/frontend/svelte/src/lib/components/lists/SessionList.svelte similarity index 69% rename from ohmg/frontend/svelte/src/lib/components/SessionList.svelte rename to ohmg/frontend/svelte/src/lib/components/lists/SessionList.svelte index 33f9ce90..179cdacb 100644 --- a/ohmg/frontend/svelte/src/lib/components/SessionList.svelte +++ b/ohmg/frontend/svelte/src/lib/components/lists/SessionList.svelte @@ -2,15 +2,17 @@ import {TableSort} from 'svelte-tablesort'; import IconContext from 'phosphor-svelte/lib/IconContext'; -import { iconProps } from "../../js/utils" +import { iconProps } from "@helpers/utils" + +import IconButton from '../base/IconButton.svelte'; import CaretDoubleLeft from 'phosphor-svelte/lib/CaretDoubleLeft' import CaretDoubleRight from 'phosphor-svelte/lib/CaretDoubleRight' import ArrowsClockwise from 'phosphor-svelte/lib/ArrowsClockwise' -import Modal, {getModal} from './Modal.svelte'; - -import InfoButton from './buttons/InfoButton.svelte'; +import Link from '@components/base/Link.svelte'; +import OpenModalButton from '@components/base/OpenModalButton.svelte'; +import SessionListModal from './modals/SessionListModal.svelte'; export let SESSION_API_URL; export let FILTER_PARAM = ''; @@ -19,7 +21,7 @@ export let limit = "10"; export let showThumbs = false; export let showUser = true; export let showResource = true; -export let allowPagination = true; +export let paginate = true; let loading = false; @@ -33,7 +35,10 @@ let baseUrl = SESSION_API_URL $: { loading = true; - let fetchUrl = `${baseUrl}?limit=${limitInt}&offset=${offset}` + let fetchUrl = `${baseUrl}?offset=${offset}` + if (limitInt > 0) { + fetchUrl = `${fetchUrl}&limit=${limitInt}` + } if (FILTER_PARAM) { fetchUrl += `&${FILTER_PARAM}` } @@ -50,32 +55,27 @@ $: { }); } -let modalContent = `When contributors complete a step in the georeferencing process, it is stored as a session, either a "preparation" session (P) or "georeference" sessions (G). (MultiMask trimming is not stored in sessions, for now.) - -If you are looking for a list of the most recently added items (volumes), go to the [items page](/search#items) and sort the table by **Load date**. - -*More sophisticated filter and sort capabilities for this list are in the works. This data is also accessible via the [beta API](/api/beta/docs). Please [get in touch](/contact) if you would like a key for the API.*` - +
- {#if allowPagination}
+ {#if paginate}
- - {offset} - {offset + limitInt < total ? offset + limitInt : total} ({total}) - + {offset = offset - limitInt}} style="lite" icon="caret-double-left" /> + {offset} - {offset + limitInt < total ? offset + limitInt : total} ({total}) + = total || loading} action={() => {offset = offset + limitInt}} style="lite" icon="caret-double-right" />
+ {:else} +
+ {/if}
{#if showResource}
{/if} + {#if limitInt != 0}
-
- -
-
- + {/if} + {offset = 1000; offset=0}} style="lite" icon="refresh" /> +
-
- {/if}
{#if loading}
@@ -132,22 +126,22 @@ If you are looking for a list of the most recently added items (volumes), go to {#if showUser} - {s.user.username} + {s.user.username} {/if} {#if showResource} {#if s.type === "p"} {#if showThumbs}{s.doc.title}{/if} - + {s.doc.title} - + {:else if s.type === "g" || s.type === "t"} {#if s.lyr} {#if showThumbs}{s.doc.title}{/if} - + {s.lyr.title} - + {/if} {/if} @@ -163,10 +157,6 @@ If you are looking for a list of the most recently added items (volumes), go to
diff --git a/ohmg/frontend/svelte/src/lib/Profile.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/Profile.svelte similarity index 54% rename from ohmg/frontend/svelte/src/lib/Profile.svelte rename to ohmg/frontend/svelte/src/lib/components/overviews/Profile.svelte index 753feb70..6bde7959 100644 --- a/ohmg/frontend/svelte/src/lib/Profile.svelte +++ b/ohmg/frontend/svelte/src/lib/components/overviews/Profile.svelte @@ -1,26 +1,25 @@ -
- +
{#if myProfile}
@@ -28,9 +27,9 @@ const sessionFilterParam = `username=${PROFILE_USER.username}`
{#if USER_API_KEYS.length > 0}

Api Keys

@@ -46,9 +45,9 @@ const sessionFilterParam = `username=${PROFILE_USER.username}`
{#if showSessions} @@ -80,7 +79,7 @@ button.section-toggle-btn { padding: 0; } -button.section-toggle-btn, a { +button.section-toggle-btn { text-decoration: none; } @@ -88,7 +87,7 @@ button.section-toggle-btn:hover { color: #1b4060; } -button.section-toggle-btn:disabled, button.section-toggle-btn:disabled > a { +button.section-toggle-btn:disabled { color: grey; } diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/Resource.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/Resource.svelte new file mode 100644 index 00000000..a0023107 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/Resource.svelte @@ -0,0 +1,560 @@ + + + +
+ + +
+ + {#if sectionVis['summary']} +
+ +
+ {/if} +
+
+ + {#if sectionVis['preview']} +
+
+ {#each reinitMap as key (key)} + {#if RESOURCE.type == "document"} + + {:else} + + {/if} + {/each} +
+
+ {/if} +
+
+ + {#if sectionVis['prep']} +
+
+ + + {#if USER.is_authenticated} + + {/if} +
+
+ {#if SPLIT_SUMMARY} +

{SPLIT_SUMMARY.date_str} by + {SPLIT_SUMMARY.user.name}: + {#if !SPLIT_SUMMARY.split_needed} + No split needed. + {:else if SPLIT_SUMMARY.child_docs.length > 0} + Split into {SPLIT_SUMMARY.child_docs.length} new document{#if SPLIT_SUMMARY.child_docs.length != 1}s{/if}, + each must be georeferenced individually. + {:else if SPLIT_SUMMARY.parent_doc} + Split from {SPLIT_SUMMARY.parent_doc.title}. + {/if} +

+ {#if SPLIT_SUMMARY.child_docs.length > 0} +
+ {#each SPLIT_SUMMARY.child_docs as child} +
+
+ {child.title.split(" | ")[1]} +
+ {child.title} +
+
    +
  • Status: {child.status}
  • +
  • + {#if child.status == "georeferenced"}edit georeferencing → + {:else}georeference → + {/if} +
  • +
+
+
+ {/each} +
+ {/if} + {/if} +
+
+ {/if} +
+
+ + {#if sectionVis['georef']} +
+
+ + {#if USER.is_authenticated && USER.is_staff} + + {/if} +
+
+ {#if GEOREFERENCE_SUMMARY.gcp_geojson} + + + + + + + + + + + {#each GEOREFERENCE_SUMMARY.gcp_geojson.features as feat} + + + + + + + + + {/each} +
{GEOREFERENCE_SUMMARY.gcp_geojson.features.length} Control Points
XYLngLatUserNote
{feat.properties.image[0]}{feat.properties.image[1]}{Math.round(feat.geometry.coordinates[0]*1000000)/1000000}{Math.round(feat.geometry.coordinates[1]*1000000)/1000000}{feat.properties.username}{feat.properties.note != null ? feat.properties.note : "--"}
+ {/if} +
+
+ {/if} +
+
+ + {#if sectionVis['history']} +
+ +
+ {/if} +
+
+
+ + diff --git a/ohmg/frontend/svelte/src/lib/components/ConditionalDoubleChevron.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/buttons/ConditionalDoubleChevron.svelte similarity index 100% rename from ohmg/frontend/svelte/src/lib/components/ConditionalDoubleChevron.svelte rename to ohmg/frontend/svelte/src/lib/components/overviews/buttons/ConditionalDoubleChevron.svelte diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/DocumentViewerModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/DocumentViewerModal.svelte new file mode 100644 index 00000000..0ae66dff --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/DocumentViewerModal.svelte @@ -0,0 +1,15 @@ + + + + {#each reinit as key (key)} + + {/each} + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/GeoreferenceOverviewModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/GeoreferenceOverviewModal.svelte new file mode 100644 index 00000000..ef2bd793 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/GeoreferenceOverviewModal.svelte @@ -0,0 +1,9 @@ + + + +

Georeferencing Overview

+

The Georeferencing Overview provides a per-document summary and access point to the entire georeferencing process for this item's content. As documents are processed, they will move through the sections from top to bottom.

+
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/GeoreferencePermissionsModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/GeoreferencePermissionsModal.svelte new file mode 100644 index 00000000..9bf7ac96 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/GeoreferencePermissionsModal.svelte @@ -0,0 +1,27 @@ + + + +

Access Settings

+

Access level: {item.access}

+

+ {#if item.access == "none"} + Only admins can georeference this item's content. + {:else if item.access == "sponsor"} + Only contributors linked to this item's sponsor can georeference it's content. + {:else if item.access == "any"} + Any logged in contributors can georeference this item's content. + {/if} +

+ + {item.status} + {item.sponsor} + + {user} + {userCanEdit} +
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/GeoreferencedSectionModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/GeoreferencedSectionModal.svelte new file mode 100644 index 00000000..bd659b44 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/GeoreferencedSectionModal.svelte @@ -0,0 +1,10 @@ + + + +

Georeferenced

+

The Georeferenced section holds all content that has been spatially rectified, though you can still edit the control points for any layer whose georeferencing should be improved.

+

Use the Classify Layers button to sort layers into different categories, if applicable. For example, if a Key Map is present, classify it here so other interfaces will treat it appropriately.

+
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/ItemDownloadSectionModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/ItemDownloadSectionModal.svelte new file mode 100644 index 00000000..3204eef1 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/ItemDownloadSectionModal.svelte @@ -0,0 +1,13 @@ + + + +

Download & Web Services

+

After multiple pages have been georeferenced and a multimask has been created, a single mosaic can be generated from all of this item's layers. Once created, the mosaic can be downloaded as a GeoTIFF, or integrated as a web service into any common GIS or web GIS software via the XYZ tiles URL.

+ +
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/ItemPreviewMapModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/ItemPreviewMapModal.svelte new file mode 100644 index 00000000..1fb5c875 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/ItemPreviewMapModal.svelte @@ -0,0 +1,14 @@ + + + +

Mosaic Preview

+

The Mosaic Preview shows progress toward a full mosaic of this item's content—as documents are georeferenced, they will automatically appear here.

+

You can also view this mosaic alongside all other mosaics for this locale: {placeName}

+
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/LayerViewerModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/LayerViewerModal.svelte new file mode 100644 index 00000000..988d7f67 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/LayerViewerModal.svelte @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/MultiMaskModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/MultiMaskModal.svelte new file mode 100644 index 00000000..bdb2e70b --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/MultiMaskModal.svelte @@ -0,0 +1,29 @@ + + + +

MultiMask

+

The MultiMask is a mechanism for trimming the margins from every layer in a way that guarantees a seamless mosaic across this item's content.

+

How to create a MultiMask

+
    +
  • Use to start a mask for a particular layer.
  • +
  • Use to delete an existing mask.
  • +
  • Use to save your work (do this often!).
  • +
  • Use to discard all changes since the last save.
  • +
+

Important Notes

+
    +
  • You must be signed in to save your work, so don't get started before you are signed in!
  • +
  • The vertices of every adjacent mask should be snapped together
  • +
  • You can drag existing vertices to snap them to others, but this is sometimes "sticky" and takes a couple of tries.
  • +
  • If a mosaic is generated for this item, only layers that have been masked will be included in the mosaic.
  • +
+
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/NonMapContentModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/NonMapContentModal.svelte new file mode 100644 index 00000000..ec00e8f0 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/NonMapContentModal.svelte @@ -0,0 +1,9 @@ + + + +

Non-Map Content

+

The Non-Map Content section holds documents (or document fragments) that are not maps, like a title page or text index.

+
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/PreparedSectionModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/PreparedSectionModal.svelte new file mode 100644 index 00000000..51887c93 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/PreparedSectionModal.svelte @@ -0,0 +1,9 @@ + + + +

Prepared

+

Content in the Prepared section is ready to be georeferenced. You can also decide here if a particular document should be moved to the Non-map Content section, for example if it is a title page or text index (this designation can be easily reversed).

+
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/ResourceDownloadSectionModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/ResourceDownloadSectionModal.svelte new file mode 100644 index 00000000..0eb001e6 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/ResourceDownloadSectionModal.svelte @@ -0,0 +1,11 @@ + + + +

Download & Web Services

+ +
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/modals/UnpreparedSectionModal.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/modals/UnpreparedSectionModal.svelte new file mode 100644 index 00000000..069a59b7 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/modals/UnpreparedSectionModal.svelte @@ -0,0 +1,9 @@ + + + +

Unprepared

+

Each document in the Unprepared section must be evaluated individually, and, if it contains more than one mapped area, split into separate pieces.

+
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/sections/HowToUseXYZ.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/sections/HowToUseXYZ.svelte new file mode 100644 index 00000000..145f5cdd --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/sections/HowToUseXYZ.svelte @@ -0,0 +1,17 @@ + + +

How to use XYZ tiles in desktop software

+
    +
  • QGIS
  • +
  • ArcGIS
  • +
+

How to use XYZ tiles on the web

+
    +
  • Leaflet
  • +
  • OpenLayers
  • +
  • Mapbox/MapLibre GL JS
  • +
  • ArcGIS Online
  • +
  • OpenHistoricalMap (iD Editor)
  • +
\ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/sections/ItemDetails.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/sections/ItemDetails.svelte new file mode 100644 index 00000000..00cc52e5 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/sections/ItemDetails.svelte @@ -0,0 +1,148 @@ + + + +
+

Item Details

+ View item in LOC collection + + + + + + + + + + + + + +
TitleSanborn Map of {ITEM.title}
Year{ITEM.year}
Locale{ITEM.locale.display_name}
+

Contributors & Attribution

+
+

+ {#if ITEM.sheet_ct.loaded == ITEM.sheet_ct.total} + {ITEM.sheet_ct.loaded} of {ITEM.sheet_ct.total} sheet{#if ITEM.sheet_ct.total != 1}s{/if} loaded by {ITEM.loaded_by.name} - {ITEM.loaded_by.date}
+ {/if} + {ITEM.sessions.prep_ct} sheet{#if ITEM.sessions.prep_ct != 1}s{/if} prepared{#if ITEM.sessions.prep_ct > 0} by + {#each ITEM.sessions.prep_contributors as c, n}{c.name} ({c.ct}){#if n != ITEM.sessions.prep_contributors.length-1}, {/if}{/each}{/if} +
+ {ITEM.sessions.georef_ct} georeferencing session{#if ITEM.sessions.georef_ct != 1}s{/if}{#if ITEM.sessions.georef_ct > 0} by + {#each ITEM.sessions.georef_contributors as c, n}{c.name} ({c.ct}){#if n != ITEM.sessions.georef_contributors.length-1}, {/if}{/each}{/if} +
+ Credit Line: Library of Congress, Geography and Map Division, Sanborn Maps Collection. +

+
+
+

Download & Web Services

+ +
+

+ Only layers that have been trimmed in the MultiMask will appear in the mosaic. You can access untrimmed layers individually through the Georeferenced section. +

+ + + + + + + + + + + + + +
XYZ Tiles URL + {#if mosaicUrl} +
{mosaicUrl}
+ {:else} + n/a + {/if} +
OHM + {#if ohmUrl} + Open in OpenHistoricalMap iD editor + {:else} + n/a + {/if}
GeoTIFF + {#if ITEM.urls.mosaic_geotiff} + Download GeoTIFF (direct download) + {:else} + n/a + {/if} +
+
+ + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/components/overviews/sections/ResourceDetails.svelte b/ohmg/frontend/svelte/src/lib/components/overviews/sections/ResourceDetails.svelte new file mode 100644 index 00000000..dab67661 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/components/overviews/sections/ResourceDetails.svelte @@ -0,0 +1,172 @@ + + + + +

Resource Details

+ + + + + + + + + +
TitleSanborn Map of {RESOURCE.title}
Status{RESOURCE.status}
+
+

Downloads & Web Services

+ +
+ + + + + + + + + + + + + + + + + +
Image + {#if jpegUrl} + JPEG + {/if} + {#if cogUrl} + • + GeoTIFF + {/if} +
Ground Control Points + {#if gcpsGeojsonUrl} + GeoJSON + + {:else} + n/a + {/if} +
XYZ Tiles URL + {#if xyzUrl} +
{xyzUrl}
+ {:else} + n/a + {/if} +
OHM + {#if ohmUrl} + Open in OpenHistoricalMap iD editor + {:else} + n/a + {/if}
+ + \ No newline at end of file diff --git a/ohmg/frontend/svelte/src/lib/Browse.svelte b/ohmg/frontend/svelte/src/lib/pages/Browse.svelte similarity index 88% rename from ohmg/frontend/svelte/src/lib/Browse.svelte rename to ohmg/frontend/svelte/src/lib/pages/Browse.svelte index 0724ddb8..21151aaa 100644 --- a/ohmg/frontend/svelte/src/lib/Browse.svelte +++ b/ohmg/frontend/svelte/src/lib/pages/Browse.svelte @@ -1,8 +1,8 @@ + + + diff --git a/ohmg/frontend/svelte/src/lib/Home.svelte b/ohmg/frontend/svelte/src/lib/pages/Home.svelte similarity index 57% rename from ohmg/frontend/svelte/src/lib/Home.svelte rename to ohmg/frontend/svelte/src/lib/pages/Home.svelte index c3189c86..9850968f 100644 --- a/ohmg/frontend/svelte/src/lib/Home.svelte +++ b/ohmg/frontend/svelte/src/lib/pages/Home.svelte @@ -1,50 +1,51 @@

OldInsuranceMaps.net

-

A crowdsourcing site for creating and viewing georeferenced mosaics of historical fire insurance maps from the Library of Congress. See how it works or visit the about or FAQ pages to learn more.

+

A crowdsourcing site for creating and viewing georeferenced mosaics of historical fire insurance maps from the Library of Congress. See how it works or visit the about or FAQ pages to learn more.

Explore georeferenced maps from {PLACES_CT} locations...

-

Click a point to access the viewer for that locale, or search by place name. +

Click a point to access the viewer for that locale, or search by place name.

{#if IS_MOBILE}{/if} {#if showBrowseMap} @@ -58,16 +59,16 @@ if (urlSegs[urlSegs.length - 2] == 'about') {

Recently Added Maps

- Want to see more? View all items and sort by Load date. + Want to see more? View all items and sort by Load date.
{#if NEWSLETTER_SLUG} @@ -76,12 +77,12 @@ if (urlSegs[urlSegs.length - 2] == 'about') { {#if USER_SUBSCRIBED} - manage subscription + manage subscription {:else} {/if} - newsletter archive + newsletter archive
{/if}
@@ -91,36 +92,46 @@ if (urlSegs[urlSegs.length - 2] == 'about') {

How it Works

-
+
+ +

- Digital scans of Sanborn maps are available through the Library of Congress and are pulled into this site through the LOC JSON API, generating a "Volume Summary" page (Baton Rouge, 1885). + Digital scans of Sanborn maps are available through the Library of Congress and are pulled into this site through the LOC JSON API, generating a "Volume Summary" page (Baton Rouge, 1885).

-
+
+ +

- Contributors prepare each sheet in the volume, sometimes splitting it into multiple documents, each to be georeferenced individually (Baton Rouge, 1885, page 1). + Contributors prepare each sheet in the volume, sometimes splitting it into multiple documents, each to be georeferenced individually (Baton Rouge, 1885, page 1).

-
+
+ +

- Next, each document must be georeferenced by creating ground control points, linking features on the old map with latitude/longitude coordinates to create a geospatial layer (Baton Rouge, 1885, page 1, part 3). + Next, each document must be georeferenced by creating ground control points, linking features on the old map with latitude/longitude coordinates to create a geospatial layer (Baton Rouge, 1885, page 1, part 3).

-
+
+ +

- As they are georeferenced, layers slowly build a collage of all the content from a given volume, and their overlapping margins must be trimmed to create a seamless mosaic. + As they are georeferenced, layers slowly build a collage of all the content from a given volume, and their overlapping margins must be trimmed to create a seamless mosaic.

-
+
+ +

- Finally, all volume mosaics for a given locale are automatically aggregated into a simple web viewer so you can easily compare different years and current maps (Baton Rouge viewer). + Finally, all volume mosaics for a given locale are automatically aggregated into a simple web viewer so you can easily compare different years and current maps (Baton Rouge viewer).

-

Want to learn more? Visit the documentation site .

+

Want to learn more? Visit the documentation site.

@@ -128,8 +139,8 @@ if (urlSegs[urlSegs.length - 2] == 'about') {

Latest activity

-

all activity

- +

all activity

+
@@ -137,7 +148,9 @@ if (urlSegs[urlSegs.length - 2] == 'about') {
diff --git a/ohmg/frontend/svelte/src/lib/Index.svelte b/ohmg/frontend/svelte/src/lib/pages/Index.svelte similarity index 68% rename from ohmg/frontend/svelte/src/lib/Index.svelte rename to ohmg/frontend/svelte/src/lib/pages/Index.svelte index cad9efed..6c3941de 100644 --- a/ohmg/frontend/svelte/src/lib/Index.svelte +++ b/ohmg/frontend/svelte/src/lib/pages/Index.svelte @@ -1,17 +1,15 @@ + + + + +
+
+ {#if PLACE.parents.length > 0} +

Super-locale

+
    + {#each PLACE.parents as d} +
  • + +
  • + {/each} +
+ {/if} + {#if PLACE.descendants.length > 0} +

Sub-locales

+
+ +
+ {#if localeList.length > 0} +
    + {#each localeList as d} +
  • + +
  • + {/each} +
+ {:else} +

---

+ {/if} + {/if} +
+
+

Maps

+ {#each reinitList as key (key)} + + {/each} +
+
+
+ + diff --git a/ohmg/frontend/svelte/src/lib/pages/Split.svelte b/ohmg/frontend/svelte/src/lib/pages/Split.svelte new file mode 100644 index 00000000..db0b77f5 --- /dev/null +++ b/ohmg/frontend/svelte/src/lib/pages/Split.svelte @@ -0,0 +1,42 @@ + + + + diff --git a/ohmg/frontend/svelte/src/entry/navbar.js b/ohmg/frontend/svelte/src/navbar.js similarity index 76% rename from ohmg/frontend/svelte/src/entry/navbar.js rename to ohmg/frontend/svelte/src/navbar.js index 97454e35..644ba1aa 100644 --- a/ohmg/frontend/svelte/src/entry/navbar.js +++ b/ohmg/frontend/svelte/src/navbar.js @@ -1,4 +1,4 @@ -import Navbar from '../lib/Navbar.svelte'; +import Navbar from '@components/layout/Navbar.svelte'; const navbar = new Navbar({ target: document.getElementById("navbar-target"), diff --git a/ohmg/frontend/svelte/src/entry/resource.js b/ohmg/frontend/svelte/src/resource.js similarity index 65% rename from ohmg/frontend/svelte/src/entry/resource.js rename to ohmg/frontend/svelte/src/resource.js index 9f95225c..0a544ae7 100644 --- a/ohmg/frontend/svelte/src/entry/resource.js +++ b/ohmg/frontend/svelte/src/resource.js @@ -1,5 +1,5 @@ -import '../css/interface.css'; -import Resource from '../lib/Resource.svelte'; +import '@src/css/interface.css'; +import Resource from '@components/overviews/Resource.svelte'; const app = new Resource({ target: document.getElementById("resource-target"), diff --git a/ohmg/frontend/svelte/src/entry/split.js b/ohmg/frontend/svelte/src/split.js similarity index 59% rename from ohmg/frontend/svelte/src/entry/split.js rename to ohmg/frontend/svelte/src/split.js index d6fbde80..bdc66943 100644 --- a/ohmg/frontend/svelte/src/entry/split.js +++ b/ohmg/frontend/svelte/src/split.js @@ -1,6 +1,6 @@ -import '../css/interface.css'; -import Split from '../lib/Split.svelte'; -import '../css/ol-overrides.css' +import '@src/css/interface.css'; +import Split from '@src/lib/pages/Split.svelte'; +import '@src/css/ol-overrides.css' const app = new Split({ target: document.getElementById("split-target"), diff --git a/ohmg/frontend/svelte/src/entry/viewer.js b/ohmg/frontend/svelte/src/viewer.js similarity index 59% rename from ohmg/frontend/svelte/src/entry/viewer.js rename to ohmg/frontend/svelte/src/viewer.js index 2e774c84..315da23a 100644 --- a/ohmg/frontend/svelte/src/entry/viewer.js +++ b/ohmg/frontend/svelte/src/viewer.js @@ -1,6 +1,6 @@ -import Viewer from '../lib/Viewer.svelte'; +import PlaceViewer from '@components/interfaces/PlaceViewer.svelte'; -const viewer = new Viewer({ +const viewer = new PlaceViewer({ target: document.getElementById("viewer-target"), props: JSON.parse(document.getElementById("viewer-props").textContent), }); diff --git a/ohmg/frontend/templates/404.html b/ohmg/frontend/templates/404.html index e08b9b07..0f54fced 100644 --- a/ohmg/frontend/templates/404.html +++ b/ohmg/frontend/templates/404.html @@ -29,7 +29,6 @@ -