Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #2246- view finder feature to fly to user-specified latitude, longitude pair #2258

Merged
merged 4 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/screenshots/views/maps/ViewfinderView.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions src/css/map-view.css
Original file line number Diff line number Diff line change
Expand Up @@ -1068,4 +1068,47 @@ other class: .ui-slider-range */

.map-help-panel__section:not(:first-child) {
margin-top: 2.5rem;
}

.viewfinder__field {
border-radius: 4px;
border: 1px solid var(--portal-col-bkg-active);
display: flex;
flex-direction: row;
background: var(--portal-col-bkg-lighter);

&:focus-within {
border-color: rgba(82, 168, 236, .8);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(82, 168, 236, .6);
}

.viewfinder__input {
border: none;
box-sizing: border-box;
flex: 1;
height: 100%;
margin: 0;

&:focus {
border: none;
box-shadow: none;
}
}

.viewfinder__button {
border: none;
border-radius: 4px;
color: var(--portal-col-buttons);
background: none;

&:hover {
color: #ffffff;
}
}
}

.viewfinder__error {
color: var(--map-col-text);
font-size: .8rem;
padding: 4px 12px;
}
5 changes: 5 additions & 0 deletions src/js/models/maps/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ define([
* a {@link LayerListView}.
* @property {Boolean} [showHomeButton=true] - Whether or not to show the
* home button in the toolbar.
* @property {Boolean} [showViewfinder=false] - Whether or not to show the
* viefinder UI and viewfinder button in the toolbar.
* @property {Boolean} [toolbarOpen=false] - Whether or not the toolbar is
* open when the map is initialized. Set to false by default, so that the
* toolbar is hidden by default.
Expand Down Expand Up @@ -159,6 +161,8 @@ define([
* the layer list in the toolbar. True by default.
* @property {Boolean} [showHomeButton=true] - Whether or not to show the
* home button in the toolbar. True by default.
* @property {Boolean} [showViewfinder=false] - Whether or not to show the
* viefinder UI and viewfinder button in the toolbar. Defaults to false.
* @property {Boolean} [toolbarOpen=false] - Whether or not the toolbar is
* open when the map is initialized. Set to false by default, so that the
* toolbar is hidden by default.
Expand Down Expand Up @@ -197,6 +201,7 @@ define([
showToolbar: true,
showLayerList: true,
showHomeButton: true,
showViewfinder: false,
toolbarOpen: false,
showScaleBar: true,
showFeatureInfo: true,
Expand Down
19 changes: 19 additions & 0 deletions src/js/templates/maps/viewfinder.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<div class="<%= classNames.baseClass %>">
<h2>Viewfinder</h2>
<span>Enter a latitude and longitude pair and click search to show that point on the map.</span>
<br /><br />
<div class="viewfinder__form-field">
<div class="viewfinder__field">
<input class="<%= classNames.input %>" type="text" placeholder="<%= placeholder %>" value="<%= inputValue %>" />
<button class="<%= classNames.button %>">
<i class="icon icon-search"></i>
</button>
</div>

<% if(errorMessage) { %>
<div class="viewfinder__error">
<%= errorMessage %>
</div>
<% } %>
</div>
</div>
93 changes: 59 additions & 34 deletions src/js/views/maps/ToolbarView.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ define(
// Sub-views - TODO: import these as needed
'views/maps/LayerListView',
'views/maps/DrawToolView',
'views/maps/HelpPanelView'
'views/maps/HelpPanelView',
'views/maps/ViewfinderView',
],
function (
$,
Expand All @@ -21,7 +22,8 @@ define(
// Sub-views
LayerListView,
DrawTool,
HelpPanel
HelpPanel,
ViewfinderView,
) {

/**
Expand Down Expand Up @@ -151,6 +153,8 @@ define(
* This can be provided instead of a view and viewOptions, in which case no
* toolbar section will be created. The function will be passed the view and the
* Map model as arguments.
* @property {function} [isVisible] A function that determines whether this
* section should be visible in the toolbar.
*/

/**
Expand All @@ -167,14 +171,20 @@ define(
viewOptions: {
model: null,
collection: 'model.layers'
}
},
isVisible(model) {
return model.get("showLayerList");
},
},
{
label: 'Home',
icon: 'home',
action: function (view, model) {
model.flyHome();
}
},
isVisible(model) {
return model.get("showHomeButton");
},
},
// We can enable to the draw tool once we have a use case for it
// {
Expand All @@ -183,6 +193,19 @@ define(
// view: DrawTool,
// viewOptions: {}
// },
{
label: 'Viewfinder',
icon: 'search',
view: ViewfinderView,
action(view, model) {
const sectionEl = this;
view.defaultActivationAction(sectionEl);
sectionEl.sectionView.focusInput();
robyngit marked this conversation as resolved.
Show resolved Hide resolved
},
isVisible(model) {
return model.get("showViewfinder");
},
},
{
label: 'Help',
icon: 'question-sign',
Expand All @@ -191,7 +214,10 @@ define(
showFeedback: 'model.showFeedback',
feedbackText: 'model.feedbackText',
showNavHelp: 'model.showNavHelp',
}
},
isVisible(model) {
return model.get("showNavHelp") || model.get("showFeedback");
},
}
],

Expand Down Expand Up @@ -219,30 +245,16 @@ define(
this.model = new Map();
}

if(this.model.get('toolbarOpen') === true) {
if (this.model.get('toolbarOpen') === true) {
this.isOpen = true;
}


// Deep clone the section options so that the original array is not
// modified
this.sections = _.map(this.sectionOptions, _.clone);

if (this.model.get("showLayerList") === false) {
this.sections = this.sections.filter(
(section) => section.label !== "Layers"
);
}
if (this.model.get("showHomeButton") === false) {
this.sections = this.sections.filter(
(section) => section.label !== "Home"
);
}
if (!this.model.get("showNavHelp") && !this.model.get("showFeedback")) {
this.sections = this.sections.filter(
(section) => section.label !== "Help"
);
}
// Check whether each section should be shown, defaulting to true.
this.sections = this.sectionOptions.filter(section => {
return typeof section.isVisible === 'function'
? section.isVisible(this.model)
: true;
});
} catch (e) {
console.log('Error initializing a ToolbarView', e);
}
Expand Down Expand Up @@ -286,14 +298,17 @@ define(
var linkEl = view.renderSectionLink(sectionOption)
var action = sectionOption.action
let contentEl = null;
let sectionView;
if (sectionOption.view) {
contentEl = view.renderSectionContent(sectionOption)
const { contentContainer, sectionContent } = view.renderSectionContent(sectionOption)
contentEl = contentContainer;
sectionView = sectionContent;
}
// Set the section to false to start
var isActive = false
// Save a reference to these elements and their status. sectionEl is an
// object that has type SectionElement (documented in comments below)
var sectionEl = { linkEl, contentEl, isActive, action }
var sectionEl = { linkEl, contentEl, isActive, action, sectionView };
view.sectionElements.push(sectionEl)
// Attach the link and content to the view
if (contentEl) {
Expand Down Expand Up @@ -336,6 +351,7 @@ define(
* section's content, and open/close the toolbar.
* @property {Boolean} isActive True if this is the active section, false
* otherwise.
* @property {Backbone.View} sectionView The associated Backbone.View instance.
*/

/**
Expand Down Expand Up @@ -451,7 +467,8 @@ define(
* specified view in that container.
* @param {SectionOption} sectionOption The view and view options that are set in
* the Section Option are used to create the content container
* @returns {HTMLElement} Returns the content container with the rendered view
* @returns {HTMLElement, Backbone.View} Returns the content container with the rendered view,
* and the Backbone.View itself.
*/
renderSectionContent: function (sectionOption) {
try {
Expand Down Expand Up @@ -481,7 +498,7 @@ define(
var sectionContent = new sectionOption.view(viewOptions)
contentContainer.appendChild(sectionContent.el)
sectionContent.render()
return contentContainer
return { contentContainer, sectionContent }
}
catch (error) {
console.log('Error rendering ToolbarView section', error);
Expand Down Expand Up @@ -527,23 +544,31 @@ define(
* @param {SectionElement} sectionEl The section to activate
*/
activateSection: function (sectionEl) {
if(!sectionEl) return;
if (!sectionEl) return;
try {
if (sectionEl.action && typeof sectionEl.action === 'function') {
const view = this;
const model = this.model;
sectionEl.action(view, model)
} else {
sectionEl.isActive = true;
sectionEl.contentEl.classList.add(this.classes.contentActive)
sectionEl.linkEl.classList.add(this.classes.linkActive)
this.defaultActivationAction(sectionEl);
}
}
catch (error) {
console.log('Failed to show a section in a ToolbarView', error);
}
},

/**
* The default action for a section being activated.
* @param {SectionElement} sectionEl The section to activate
*/
defaultActivationAction(sectionEl) {
sectionEl.isActive = true;
sectionEl.contentEl.classList.add(this.classes.contentActive)
sectionEl.linkEl.classList.add(this.classes.linkActive)
},

/**
* Hide the content of a section
* @param {SectionElement} sectionEl The section to inactivate
Expand Down
Loading
Loading