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/51 bookmarks widget #200

Merged
merged 39 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
985dd8f
initial widget class setup
seahro Jun 13, 2023
c473ade
add bookmarks to widgets.razor
seahro Jun 13, 2023
6354db8
add bookmars to navmenu
seahro Jun 13, 2023
7762f2f
working on arcGisJsInterop
seahro Jun 13, 2023
fa590f3
working on arcgisjsinterop
seahro Jun 13, 2023
ed44896
Merge branch 'develop' into feature/181_bookmarks_widget
seahro Jul 10, 2023
1d96b96
Merge branch 'develop' into feature/181_bookmarks_widget
seahro Jul 11, 2023
9e0720c
bookmark widget .cs complete js interop working...
seahro Jul 11, 2023
a02a94a
add bookmark in definitions
seahro Jul 12, 2023
71bf8d8
adjusting bookmark widget
seahro Jul 12, 2023
501bb14
working on widgets page and bookmark class
seahro Jul 12, 2023
3364906
working
seahro Jul 13, 2023
040deb2
working on widget
seahro Jul 13, 2023
d8859a7
merge conflict resolved
seahro Jul 13, 2023
2dd80c8
bookmark page map rendering working on individual bookmarks
seahro Jul 13, 2023
d5c788c
building expand widget to hold bookmarks
seahro Jul 14, 2023
1f92e12
wip bookmarks
AndersenBell Jul 14, 2023
efe1d57
working
seahro Jul 14, 2023
bd44d4d
updating with branch 51
seahro Jul 14, 2023
f46d028
fixing viewpoint
AndersenBell Jul 14, 2023
7d419d7
separating bookmark and viewpoint classes into individual files
seahro Jul 14, 2023
46ee506
merging 181 and 51
seahro Jul 14, 2023
e245534
working on merge conflicts
seahro Jul 14, 2023
c996387
fixing some things
AndersenBell Jul 14, 2023
87ba7b8
updating naming of class
AndersenBell Jul 17, 2023
9cd95f4
adding time extent and thumbnails
AndersenBell Jul 17, 2023
0ce01bb
Adding support for expander properties
AndersenBell Jul 17, 2023
6bd3769
adding expand mode
AndersenBell Jul 18, 2023
697d343
Merge branch 'develop' into feature/51-bookmarks-widget
AndersenBell Jul 18, 2023
a323b46
code review feedback
AndersenBell Jul 19, 2023
cbeca17
Merge branch 'develop' into feature/51-bookmarks-widget
AndersenBell Jul 19, 2023
8f3f4c3
removing bookmark page
AndersenBell Jul 19, 2023
8c040e2
code review feedback
AndersenBell Jul 19, 2023
445614f
getting bookmark example working
AndersenBell Jul 21, 2023
03cedb1
Merge branch 'feature/51-bookmarks-widget' into feature/bookmark-testing
AndersenBell Jul 21, 2023
25adc96
Merge branch 'feature/bookmark-testing' into feature/51-bookmarks-widget
AndersenBell Jul 21, 2023
1dcf3ce
Merge branch 'develop' into feature/51-bookmarks-widget
AndersenBell Jul 21, 2023
4c28e8a
code review feedback
AndersenBell Jul 21, 2023
737b14e
fixing comment
AndersenBell Jul 21, 2023
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@page "/Bookmarks"
@using dymaptic.GeoBlazor.Core.Components.Widgets;

<PageTitle>Bookmarks and Bookmarks Widget</PageTitle>
<h1>Bookmarks Widget</h1>

<div class="links-div">
<a class="btn btn-secondary" target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Bookmarks.html">ArcGIS API for JavaScript Reference</a>
<a class="btn btn-primary" target="_blank" href="https://www.arcgis.com/home/item.html?id=70b726074af04a7e9839d8a07f64c039">Bookmarks widget</a>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text on this line should say "Hurricanes", i.e., the name of the layer.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still need to update the text here.

</div>

<p class="instructions">
Sample demonstrates the use of the Bookmarks widget and Bookmark actions.
</p>

<div class="form-group">
<label>Show Bookmarks and Bookmarks Widget: <input type="checkbox" class="form-check-input" @onchange="@(()=> _showBookmarks = !_showBookmarks)"></label>
</div>

<MapView @ref="MapView" Class="map-view">
<Map>
<Basemap>
<PortalItem Id="70b726074af04a7e9839d8a07f64c039" />
</Basemap>
</Map>
@if (_showBookmarks)
{
<ExpandWidget ContainerId="BookmarkDiv" Position="OverlayPosition.TopRight">
<div class="container">
<div class="row">
<div class="col-12">
<p>Click on a bookmark to navigate to its location.</p>
<BookmarksWidget />
</div>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this page not finished? Or does the BookmarksWidget really work with no parameters?

</div>
</div>
</ExpandWidget>
}






</MapView>

@code {
private MapView? MapView { get; set; }
private bool _showBookmarks;



}
85 changes: 85 additions & 0 deletions samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/Widgets.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@page "/widgets"
@using GeoBlazor.Core.Components.Widgets;

<PageTitle>Widgets</PageTitle>
<h1>Widgets</h1>
Expand Down Expand Up @@ -37,6 +38,10 @@
<div class="form-group">
<label>Compass: <input type="checkbox" class="form-check-input" @onchange="@(() => ToggleWidget(nameof(CompassWidget)))"></label>
</div>

<div class="form-group">
<label>Bookmarks + Expander: <input type="checkbox" class="form-check-input" @onchange="@(() => ToggleWidget(nameof(BookmarksWidget)))"></label>
</div>
<div id="gallery-box"></div>
</div>
</div>
Expand Down Expand Up @@ -76,6 +81,20 @@
{
<CompassWidget Position="OverlayPosition.TopLeft" />
}
@if (_showBookmarks)
{
<ExpandWidget Position="OverlayPosition.TopRight" Expanded="true" ExpandIcon="refresh" CollapseIcon="submit" >
<BookmarksWidget @ref="_bookmarkWidget" EditingEnabled="true">
@*<Bookmark Name="InlineExample">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we moved the inline markup example to the Bookmarks.razor page?

<Viewpoint >
<Extent Xmin="-13139131.948889678" Ymin="4047767.307589972" Xmax="-13105131.948889678" Ymax="4067767.307589972">
<SpatialReference Wkid="102100"></SpatialReference>
</Extent>
</Viewpoint>
</Bookmark>*@
</BookmarksWidget>
</ExpandWidget>
}
</MapView>

@code {
Expand Down Expand Up @@ -109,9 +128,72 @@
case nameof(CompassWidget):
_showCompass = !_showCompass;
break;
case nameof(BookmarksWidget):
_showBookmarks = !_showBookmarks;
break;
}
}

protected override void OnAfterRender(bool firstRender)
{
if (_showBookmarks)
{
//the MapView.Refresh() is needed because the bookmarks are added after the BookmarksWidget is rendered
_bookmarkWidget!.Bookmarks = _bookmarks;
MapView!.Refresh();
}
}

private List<Bookmark> _bookmarks = new List<Bookmark>()
{
new Bookmark()
{
Name="Angeles National Forest",
Thumbnail="/_content/dymaptic.GeoBlazor.Core.Sample.Shared/images/Blazor-API-60px.png",
Viewpoint = new Viewpoint()
{
TargetGeometry = new Extent()
{
SpatialReference = new SpatialReference(102100),
Xmin = -13139131.948889678,
Ymin = 4047767.23531948,
Xmax = -13092887.54677721,
Ymax = 4090610.189673263,
}
}
},
new Bookmark()
{
Name = "Crystal Lake",
Viewpoint = new Viewpoint()
{
TargetGeometry = new Extent()
{
SpatialReference = new SpatialReference(102100),
Xmin = -13125852.551697943,
Ymin = 4066904.1101411926,
Xmax = -13114291.451169826,
Ymax = 4077614.8487296384
}
}
},
new Bookmark()
{
Name = "Mt. Waterman",
Viewpoint = new Viewpoint()
{
TargetGeometry = new Extent()
{
SpatialReference = new SpatialReference(102100),
Xmin= -13185668.186639601,
Ymin= 4066176.418652561,
Xmax= -13183855.195875114,
Ymax= 4067515.260976006
}
}
}
};

private bool _showSearch;
private bool _showLocate;
private bool _showBasemapToggle;
Expand All @@ -120,4 +202,7 @@
private bool _showLegend;
private bool _showHome;
private bool _showCompass;
private bool _showBookmarks;

private BookmarksWidget? _bookmarkWidget;
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
new("basemaps", "Basemaps", "oi-map"),
new("feature-layers", "Feature Layers", "oi-layers"),
new("popups", "Popups", "oi-chat"),
new("bookmarks", "Bookmarks", "oi-bookmark"),
new("popup-actions", "Popup Actions", "oi-bullhorn"),
new("vector-layer", "Vector Layer", "oi-arrow-right"),
new("layer-lists", "Layer Lists", "oi-list"),
Expand Down
62 changes: 62 additions & 0 deletions src/dymaptic.GeoBlazor.Core/Components/Views/Viewpoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using dymaptic.GeoBlazor.Core.Components.Geometries;
using dymaptic.GeoBlazor.Core.Components.Widgets;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace dymaptic.GeoBlazor.Core.Components.Views;

public class Viewpoint : MapComponent
AndersenBell marked this conversation as resolved.
Show resolved Hide resolved
{
///public Camera Camera { get; set; }

/// <summary>
/// The rotation of due north in relation to the top of the view in degrees.
/// </summary>
[Parameter]
public int? Rotation { get; set; } = 0;

/// <summary>
/// The scale of the viewpoint.
/// </summary>
[Parameter]
public int Scale { get; set; } = 0;

/// <summary>
/// The target geometry framed by the viewpoint.
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Geometry? TargetGeometry { get; set; }

public override async Task RegisterChildComponent(MapComponent child)
AndersenBell marked this conversation as resolved.
Show resolved Hide resolved
{
switch (child)
{
case Geometry geometry:
TargetGeometry = geometry;
break;
default:
await base.RegisterChildComponent(child);
break;
}
}

public override async Task UnregisterChildComponent(MapComponent child)
{
switch (child)
{
case Geometry geometry:
TargetGeometry = null;
break;
default:
await base.UnregisterChildComponent(child);
break;
}

}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's one more method I'd like us to get in the habit of overriding, internal override ValidateRequiredChildren(). In that, you call each "registered" child like Child.ValidateRequiredChildren(). This is what makes the [RequiredProperty] attribute work.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, I don't think any of your children have required props, but it's still good if we do this everywhere.

}
71 changes: 71 additions & 0 deletions src/dymaptic.GeoBlazor.Core/Components/Widgets/Bookmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using dymaptic.GeoBlazor.Core.Components.Views;
using dymaptic.GeoBlazor.Core.Objects;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace dymaptic.GeoBlazor.Core.Components.Widgets;

public class Bookmark : MapComponent
AndersenBell marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// /// The extent of the specified bookmark.
/// /// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public TimeExtent? TimeExtent { get; set; }
///
/// /// <summary>
/// /// The name of the bookmark.
/// /// </summary>
AndersenBell marked this conversation as resolved.
Show resolved Hide resolved
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Name { get; set; }

/// <summary>
/// The URL for a thumbnail image.
/// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Thumbnail { get; set; }

/// <summary>
/// The URL for a thumbnail image.
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Viewpoint? Viewpoint { get; set; }


public override async Task RegisterChildComponent(MapComponent child)
AndersenBell marked this conversation as resolved.
Show resolved Hide resolved
{
switch (child)
{
case Viewpoint viewpoint:
Viewpoint = viewpoint;
break;
default:
await base.RegisterChildComponent(child);
break;
}
}

public override async Task UnregisterChildComponent(MapComponent child)
{
switch (child)
{
case Viewpoint viewpoint:
Viewpoint = null;
break;
default:
await base.UnregisterChildComponent(child);
break;
}
}
}



79 changes: 79 additions & 0 deletions src/dymaptic.GeoBlazor.Core/Components/Widgets/BookmarksWidget.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Microsoft.AspNetCore.Components;
using System.Text.Json.Serialization;


namespace dymaptic.GeoBlazor.Core.Components.Widgets;

/// <summary>
/// The Bookmarks widget allows end users to quickly navigate to a particular area of interest. It displays a list of bookmarks, which are typically defined inside the WebMap.
/// <a target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Bookmarks.html">
/// ArcGIS
/// JS API
/// </a>
/// </summary>
public class BookmarksWidget : Widget
{
/// <inheritdoc />
[JsonPropertyName("type")]
public override string WidgetType => "bookmarks";

/// <summary>
/// When true, the widget is visually withdrawn and cannot be interacted with.
/// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? Disabled { get; set; }


/// <summary>
/// Indicates whether the bookmarks are able to be edited.
/// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? EditingEnabled { get; set; }

/// <summary>
/// Indicates the heading level to use for the message "No bookmarks" when no bookmarks are available in this widget.
/// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? HeadingLevel { get; set; }

/// <summary>
/// A collection of Bookmarks.
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public List<Bookmark> Bookmarks { get; set; } = new();


/// <inheritdoc />
public override async Task RegisterChildComponent(MapComponent child)
{
switch (child)
{
case Bookmark bookmark:
if (!Bookmarks.Contains(bookmark)) Bookmarks.Add(bookmark);
WidgetChanged = true;
break;
default:
await base.RegisterChildComponent(child);
break;
}
}


/// <inheritdoc />
public override async Task UnregisterChildComponent(MapComponent child)
{
switch (child)
{
case Bookmark bookmark:
if (Bookmarks.Contains(bookmark)) Bookmarks.Remove(bookmark);
WidgetChanged = true;
break;
default:
await base.UnregisterChildComponent(child);
break;
}
}
}
Loading