-
-
Notifications
You must be signed in to change notification settings - Fork 20
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/70 add wcslayer #204
Changes from 24 commits
8d35418
dbbc0c2
2b0522c
dfa1c77
5a47c3f
db3c255
3312ec2
4766c02
aac38d7
a2956e7
54525e2
4648a5a
87fddb5
d3e154c
1eba18c
2812782
b252340
4a617db
e57049f
8b7df91
23bf08d
34bba50
496554c
d7779bc
0090d1a
3826a2e
27120e6
2ada0a3
30241bf
44e6d7f
2e00b1b
08f4674
2024863
8c8e89a
15ebcbf
160b292
118a10f
03dd90e
9391fa3
23be778
a197586
4825b16
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
@page "/wcslayers" | ||
@using dymaptic.GeoBlazor.Core.Components.Renderers.ColorRamps; | ||
|
||
<h3>WCS Layers</h3> | ||
|
||
<div class="links-div"> | ||
<a class="btn btn-secondary" target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-WCSLayer.html">ArcGIS API for JavaScript</a> | ||
<a class="btn btn-primary" target="_blank" href="something">NOAA Sea Surface Temperature Charts</a> | ||
</div> | ||
<Label>Add the sample WCS Layer URL to see a visualization of global sea surface temperature data:</Label> | ||
<InputText @bind-Value="_wcsLayerUrl"></InputText> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know that we really need this input field. I doubt anyone is going to test their own layers in our samples page. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed. I think for some samples it makes sense to have the input field, others really dont need it. |
||
<button disabled="@(!_mapRendered)" @onclick="(()=>AddRemoveWCSLayer())">Add the WCS Layer with color ramp enabled</button> | ||
<button disabled="@(!_mapRendered)" @onclick="(()=>_markup = !_markup)">Add new WCS Layer in Markup without colorizing</button> | ||
|
||
<MapView @ref="_view" class="map-view" OnMapRendered="OnMapRendered" Scale="0"> | ||
<Map ArcGISDefaultBasemap="arcgis-light-gray"> | ||
@if (_markup) | ||
{ | ||
<WCSLayer Url="https://sampleserver6.arcgisonline.com/arcgis/services/ScientificData/SeaTemperature/ImageServer/WCSServer?request=GetCapabilities&service=WCS"></WCSLayer> | ||
} | ||
|
||
|
||
</Map> | ||
</MapView> | ||
|
||
@code { | ||
|
||
|
||
|
||
private void OnMapRendered() => _mapRendered = true; | ||
|
||
public async Task AddRemoveWCSLayer() | ||
{ | ||
WCSLayer wcsSampleLayer = new() | ||
{ | ||
Url = _wcsLayerUrl, | ||
Renderer = CreateRenderer(), | ||
MultidimensionalDefinition = CreateDimensionalDefinition(), | ||
Opacity = 0.5 | ||
}; | ||
|
||
if (!_view.Map.Layers.Any()) | ||
{ | ||
await _view.AddLayer(wcsSampleLayer); | ||
} | ||
else | ||
{ | ||
_view.Map.Layers.Clear(); | ||
} | ||
_view.Refresh(); | ||
|
||
} | ||
|
||
public DimensionalDefinition CreateDimensionalDefinition() | ||
{ | ||
// initializes the dimensional filter for the raster display | ||
DimensionalDefinition? multidimensionalDefinition = new DimensionalDefinition() | ||
{ | ||
VariableName = "water_temp", // water temp at sea level | ||
DimensionName = "StdZ", | ||
Values = new List<int>(0) | ||
}; | ||
return multidimensionalDefinition; | ||
} | ||
|
||
|
||
public RasterStretchRenderer CreateRenderer() | ||
{ | ||
// This initializes the renderer as a standard deviation type | ||
var displayRenderer = new RasterStretchRenderer | ||
{ | ||
StretchType = StretchType.StandardDeviation, | ||
Statistics = new List<int>{-3, 37, 1, 1} | ||
}; | ||
|
||
var toFromColor1 = new AlgorithmicColorRamp | ||
{ | ||
FromColor = new MapColor( 0, 0, 255 ), | ||
ToColor = new MapColor ( 0, 255, 255 ) | ||
}; | ||
//multipartColorRamp.ColorRamps?.Append(toFromColor1); | ||
var toFromColor2 = new AlgorithmicColorRamp | ||
{ | ||
FromColor = new MapColor ( 0, 255, 255 ), | ||
ToColor = new MapColor ( 255, 255, 0 ) | ||
}; | ||
//multipartColorRamp.ColorRamps?.Append(toFromColor2); | ||
var toFromColor3 = new AlgorithmicColorRamp | ||
{ | ||
FromColor = new MapColor ( 255, 255, 0 ), | ||
ToColor = new MapColor ( 255, 0, 0 ) | ||
}; | ||
//multipartColorRamp.ColorRamps?.Append(toFromColor3); | ||
|
||
// Builds the multipart color ramp | ||
MultipartColorRamp? multipartColorRamp = new() | ||
{ | ||
AlgorithmicColorRamps = new AlgorithmicColorRamp[] | ||
{ | ||
toFromColor1, | ||
toFromColor2, | ||
toFromColor3 | ||
} | ||
}; | ||
|
||
// initializes the colorRamp for the renderer, the color ramp contains the type and specific colorizing details from the MultipartColorRamp collection for the renderer | ||
var colorRamp = new ColorRamp | ||
{ | ||
Type = "multipart", | ||
MultipartColorRamps = multipartColorRamp | ||
|
||
}; | ||
//finalizes the renderer with all the color ramp values | ||
displayRenderer.ColorRamps = colorRamp; | ||
return displayRenderer; | ||
} | ||
|
||
private AlgorithmicColorRamp[]? _colorRampsList; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not used. I'll stop harping, but please check for unused variables when cleaning up code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, and no worries. |
||
private MultipartColorRamp? multipartColorRamp; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not used. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. corrected |
||
|
||
|
||
|
||
private MapView _view; | ||
private bool _markup = false; | ||
private bool _visible = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. corrected |
||
private bool _mapRendered = false; | ||
|
||
|
||
//private string _wcsLayerUrl = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/WCS/SeaTemperature/ImageServer"; | ||
private string _wcsLayerUrl2 = "https://sampleserver6.arcgisonline.com/arcgis/services/ScientificData/SeaTemperature/ImageServer/WCSServer"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This variable is never used and can be deleted. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. an oversight while I was cleaning up the file...corrected. |
||
private string _wcsLayerUrl = "https://sampleserver6.arcgisonline.com/arcgis/services/ScientificData/SeaTemperature/ImageServer/WCSServer?request=GetCapabilities&service=WCS"; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,19 +3,20 @@ | |
<PropertyGroup> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> | ||
<UserSecretsId>0d722028-1f33-4f5f-829c-e1333fd73878</UserSecretsId> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. user secrets do not work AFAIK in wasm, hence why these were not here before. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually, they do work in both server and wasm. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. both references are now removed from csproj files |
||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5"/> | ||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all"/> | ||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\dymaptic.GeoBlazor.Core.Sample.Shared\dymaptic.GeoBlazor.Core.Sample.Shared.csproj"/> | ||
<ProjectReference Include="..\dymaptic.GeoBlazor.Core.Sample.Shared\dymaptic.GeoBlazor.Core.Sample.Shared.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Content Remove="staticwebapp.config.json"/> | ||
<Content Remove="staticwebapp.config.json" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -191,7 +191,7 @@ internal override void ValidateRequiredChildren() | |
/// </param> | ||
internal virtual Task UpdateFromJavaScript(Layer renderedLayer) | ||
{ | ||
if (renderedLayer.FullExtent is not null) | ||
if (renderedLayer?.FullExtent is not null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was corrected by adding "wcs" as a layer type to the layerConverter in |
||
{ | ||
FullExtent = renderedLayer.FullExtent; | ||
} | ||
|
@@ -276,6 +276,8 @@ internal class LayerConverter : JsonConverter<Layer> | |
return JsonSerializer.Deserialize<CSVLayer>(ref cloneReader, newOptions); | ||
case "kml": | ||
return JsonSerializer.Deserialize<KMLLayer>(ref cloneReader, newOptions); | ||
//case "wcs": | ||
// return JsonSerializer.Deserialize<WCSLayer>(ref cloneReader, newOptions); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
using dymaptic.GeoBlazor.Core.Components.Renderers; | ||
using dymaptic.GeoBlazor.Core.Exceptions; | ||
using Microsoft.AspNetCore.Components; | ||
using System.Text.Json.Serialization; | ||
|
||
|
||
namespace dymaptic.GeoBlazor.Core.Components.Layers; | ||
|
||
/// <summary> | ||
/// WCS presents raster data from a OGC Web Coverage Service. Raster data are projected and rendered on the client-side. | ||
/// It supports versions 1.0.0, 1.1.0, 1.1.1, 1.1.2 and 2.0.1. For version 2.0.1, it supports servers that support | ||
/// GEOTIFF coverage and implements the following extensions: Scaling, Interpolation, Range Subsetting, CRS, and KVP/Get. | ||
/// <a target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-WCSLayer.html"> | ||
/// ArcGIS | ||
/// JS API | ||
/// </a> | ||
/// </summary> | ||
public class WCSLayer : Layer | ||
{ | ||
/// <inheritdoc /> | ||
[JsonPropertyName("type")] | ||
public override string LayerType => "wcs"; | ||
|
||
/// <summary> | ||
/// Constructor for use as a razor component | ||
/// </summary> | ||
public WCSLayer() | ||
{ | ||
} | ||
/// <summary> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there should be a space before these comments, and not one after them, for consistency. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Corrected across all the class files. |
||
/// Constructor for use in code | ||
/// </summary> | ||
/// <param name="url"> | ||
/// The url for the WCS Layer source data. | ||
/// </param> | ||
|
||
public WCSLayer(string? url = null, PortalItem? portalItem = null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add |
||
{ | ||
if (url is null && portalItem is null) | ||
{ | ||
throw new MissingRequiredOptionsChildElementException(nameof(WCSLayer), | ||
new[] {nameof(Url), nameof(PortalItem)}); | ||
} | ||
Url = url; | ||
PortalItem = portalItem; | ||
} | ||
|
||
[Parameter] | ||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | ||
[RequiredProperty(nameof(PortalItem))] | ||
public string? Url { get; set; } | ||
|
||
/// <summary> | ||
/// The portal item for the KML Layer source data. | ||
/// </summary> | ||
[RequiredProperty(nameof(Url))] | ||
public PortalItem? PortalItem { get; set; } | ||
/// <summary> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. always have a space between properties and/or xml comments There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. corrected |
||
/// The multidimensional definitions associated with the layer. | ||
/// </summary> | ||
public DimensionalDefinition? MultidimensionalDefinition { get; set; } | ||
/// <summary> | ||
/// The renderer assigned to the layer. | ||
/// </summary> | ||
public RasterStretchRenderer Renderer { get; set; } | ||
|
||
/// <inheritdoc /> | ||
public override async Task RegisterChildComponent(MapComponent child) | ||
{ | ||
switch (child) | ||
{ | ||
case PortalItem portalItem: | ||
if (!portalItem.Equals(PortalItem)) | ||
{ | ||
PortalItem = portalItem; | ||
LayerChanged = true; | ||
} | ||
break; | ||
case DimensionalDefinition dimensionalDefinition: | ||
if (!dimensionalDefinition.Equals(MultidimensionalDefinition)) | ||
{ | ||
MultidimensionalDefinition = dimensionalDefinition; | ||
LayerChanged = true; | ||
} | ||
break; | ||
case RasterStretchRenderer rasterStretchRenderer: | ||
if (!rasterStretchRenderer.Equals(Renderer)) | ||
{ | ||
Renderer = rasterStretchRenderer; | ||
LayerChanged = true; | ||
} | ||
break; | ||
default: | ||
await base.RegisterChildComponent(child); | ||
|
||
break; | ||
} | ||
} | ||
/// <inheritdoc /> | ||
public override async Task UnregisterChildComponent(MapComponent child) | ||
{ | ||
switch (child) | ||
{ | ||
case PortalItem _: | ||
PortalItem = null; | ||
LayerChanged = true; | ||
break; | ||
case DimensionalDefinition _: | ||
MultidimensionalDefinition = null; | ||
LayerChanged = true; | ||
break; | ||
case RasterStretchRenderer _: | ||
Renderer = null; | ||
LayerChanged = true; | ||
break; | ||
default: | ||
await base.UnregisterChildComponent(child); | ||
|
||
break; | ||
} | ||
} | ||
/// <inheritdoc /> | ||
internal override void ValidateRequiredChildren() | ||
{ | ||
PortalItem?.ValidateRequiredChildren(); | ||
MultidimensionalDefinition?.ValidateRequiredChildren(); | ||
Renderer?.ValidateRequiredChildren(); | ||
base.ValidateRequiredChildren(); | ||
} | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using dymaptic.GeoBlazor.Core.Extensions; | ||
using dymaptic.GeoBlazor.Core.Objects; | ||
using dymaptic.GeoBlazor.Core.Serialization; | ||
using Microsoft.AspNetCore.Components; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
using System.Threading.Tasks; | ||
|
||
namespace dymaptic.GeoBlazor.Core.Components.Renderers.ColorRamps; | ||
|
||
/// <summary> | ||
/// Creates a color ramp for use in a raster renderer. The algorithmic color ramp is defined by specifying two colors and the | ||
/// algorithm used to traverse the intervening color spaces. | ||
/// <a target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-AlgorithmicColorRamp.html"> | ||
/// ArcGIS | ||
/// JS API | ||
/// </a> | ||
/// </summary> | ||
public class AlgorithmicColorRamp : ColorRamp | ||
{ | ||
public AlgorithmicColorRamp() { } | ||
/// <summary> | ||
/// A string value representing the color ramp type. | ||
/// </summary> | ||
//[JsonPropertyName("type")] | ||
//public string? Type { get; set; } | ||
|
||
/// <summary> | ||
/// The algorithm used to generate the colors between the fromColor and toColor. | ||
/// </summary> | ||
|
||
public Algorithm Algorithm { get; set; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To support inheriting from MapComponent
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. parameters and constructors are now included |
||
/// <summary> | ||
/// The first color in the color ramp. | ||
/// </summary> | ||
public MapColor? FromColor { get; set; } | ||
/// <summary> | ||
/// The last color in the color ramp. | ||
/// </summary> | ||
public MapColor? ToColor { get; set; } | ||
} | ||
/// <summary> | ||
/// The algorithm used to generate the colors between the fromColor and toColor. Each algorithm uses different methods for generating the intervening colors. | ||
/// </summary> | ||
[JsonConverter(typeof(EnumToKebabCaseStringConverter<Algorithm>))] | ||
public enum Algorithm | ||
{ | ||
CieLab, | ||
LabLch, | ||
Hsv | ||
} | ||
|
||
//internal class AlgorithmConverter : JsonConverter<Algorithm> | ||
//{ | ||
// public override Algorithm Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
// { | ||
// throw new NotImplementedException(); | ||
// } | ||
|
||
// public override void Write(Utf8JsonWriter writer, Algorithm value, JsonSerializerOptions options) | ||
// { | ||
// string? stringVal = Enum.GetName(typeof(Algorithm), value); | ||
// string resultString = stringVal!.ToKebabCase(); | ||
// writer.WriteRawValue($"\"{resultString}\""); | ||
// } | ||
//} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this to
_Imports.razor