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

Adding CSV Layer #169

Merged
merged 8 commits into from
Jul 13, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
</ProjectExtensions>

<Target Name="Copy Source Files" BeforeTargets="DispatchToInnerBuilds">
<Message Importance="high" Text="Running NPM Install"/>
<Message Importance="high" Text="Copying examples for source display"/>
<Exec ContinueOnError="true" Command="robocopy ..\dymaptic.GeoBlazor.Core.Sample.Shared\wwwroot\pages\ Resources\Raw\"/>
</Target>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@page "/csv-layer"
@using System.Reflection.Metadata
@using dymaptic.GeoBlazor.Core.Components
@using dymaptic.GeoBlazor.Core.Components.Geometries
@using dymaptic.GeoBlazor.Core.Components.Views
@using Microsoft.AspNetCore.Components
@using Microsoft.AspNetCore.Components.Forms
<h3>CSV Layers</h3>

<div class="links-div">
<a class="btn btn-secondary" target="_blank" href="https://developers.arcgis.com/javascript/latest/layers-and-data/">ArcGIS API for JavaScript</a>
</div>
<Label>Enter CSV Layer URL:</Label>
<InputText @bind-Value="_csvLayerUrl"></InputText>
<button disabled="@(!_mapRendered)" @onclick="AddLayer">Add new CSV Layer!</button>


<MapView @ref="_view" class="map-view" OnMapRendered="OnMapRendered">
<Extent Xmin="-41525513" Ymin="4969181" Xmax="-36687355" Ymax="9024624">
<SpatialReference Wkid="102100" />
</Extent>
<Map ArcGISDefaultBasemap="arcgis-topographic">
<CSVLayer Url="https://developers.arcgis.com/javascript/latest//sample-code/layers-csv/live/earthquakes.csv" Title="Earth Quakes" Copyright="Esri"></CSVLayer>
</Map>
</MapView>

@code {

private void OnMapRendered()
{
_mapRendered = true;
}

private async Task AddLayer()
{
if (!string.IsNullOrEmpty(_csvLayerUrl))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we remove the original CSV layer when adding a new one? Did you try binding to the <CSVLayer Url="_csvLayerUrl"> value? I'm sure there could be issues with that, you might have to call mapView.Refresh().

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I didn't try it. I was trying to include multiple examples of adding a csv layer, so if you look at the source you can see how to do it declaratively and programmatically.

{
//we create a custom CSVLayer from a CSV url
var csvLayer = new CSVLayer(_csvLayerUrl);

if (_mapRendered)
{
await _view.AddLayer(csvLayer);
}
}
}

private string? _csvLayerUrl;

private MapView? _view;

private bool _mapRendered;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<button disabled="@(!_mapRendered)" @onclick="() => ToggleLayer(_graphicsLayer)">Graphics Layer</button>
<button disabled="@(!_mapRendered)" @onclick="() => ToggleLayer(_geoJsonLayer)">GeoJSON Layer</button>
<button disabled="@(!_mapRendered)" @onclick="() => ToggleLayer(_geoRssLayer)">GeoRSS Layer</button>
<button disabled="@(!_mapRendered)" @onclick="() => ToggleLayer(_csvLayer)">CSV Layer</button>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you create a full samples page for this new layer type? It helps with the discoverability, and this tests page is a mess that I don't publish to our samples.geoblazor.com site.

<button disabled="@(!_mapRendered)" @onclick="() => ToggleLayer(_osmLayer)">OpenStreetMaps Layer</button>
<h2>Markup Layers</h2>
<button disabled="@(!_mapRendered)" @onclick="() => _showGraphicsMarkupLayer = !_showGraphicsMarkupLayer">Graphics Layer</button>
Expand Down Expand Up @@ -170,6 +171,8 @@
new("https://services3.arcgis.com/GVgbJbqm8hXASVYi/ArcGIS/rest/services/World_Countries_(Generalized)/FeatureServer/0/query?where=1%3D1&outFields=*&f=geojson");
private readonly GeoRSSLayer _geoRssLayer =
new("https://disasterscharter.org/charter-portlets/cpi-mvc/activations/feed/rss/");
private readonly CSVLayer _csvLayer =
new("https://developers.arcgis.com/javascript/latest//sample-code/layers-csv/live/earthquakes.csv");
private readonly OpenStreetMapLayer _osmLayer = new();

private bool _mapRendered;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
new("vector-layer", "Vector Layer", "oi-arrow-right"),
new("layer-lists", "Layer Lists", "oi-list"),
new("basemap-layer-lists", "Basemap Layer Lists", "oi-spreadsheet"),
new("csv-layer", "CSV Layers", "oi-grid-four-up"),
new("georss-layer", "GeoRSS Layer", "oi-rss"),
new("osm-layer", "OpenStreetMaps Layer", "oi-envelope-open"),
new("web-map", "Web Map", "oi-browser"),
Expand Down
7 changes: 6 additions & 1 deletion samples/dymaptic.GeoBlazor.Core.Sample.Shared/razorCopy.ps1
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
Get-ChildItem -Path .\Pages -Filter "*.razor" -File |
$path = ".\wwwroot\pages\"
If(!(test-path -PathType container $path))
{
New-Item -ItemType Directory -Path $path
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for adding this!

Get-ChildItem -Path .\Pages -Filter "*.razor" -File |
ForEach-Object { Copy-Item -Path $_.FullName -Destination ".\wwwroot\pages\$( $_.BaseName ).html" }
78 changes: 78 additions & 0 deletions src/dymaptic.GeoBlazor.Core/Components/Layers/CSVLayer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Microsoft.AspNetCore.Components;
using System.Text.Json.Serialization;


namespace dymaptic.GeoBlazor.Core.Components.Layers;

/// <summary>
/// The CSVLayer is a point layer based on a CSV file (.csv, .txt). CSV is a plain-text file format used to
/// represent tabular data, including geographic point features (latitude, longitude). Typically the latitude
/// coordinate is the Y value, and the longitude coordinate is the X value. The X, Y coordinates must be stored
/// in SpatialReference.WGS84 in csv feed.
/// <a target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-CSVLayer.html">
/// ArcGIS
Copy link
Collaborator

Choose a reason for hiding this comment

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

These line breaks cause issues with our docs generation, I believe. We might need to inline this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ok, I think it was auto-formatted this way

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It looks like its formatted exactly like other layers in the project

/// JS API
/// </a>
/// </summary>
public class CSVLayer : Layer
{
/// <summary>
/// Parameterless constructor for use as a razor component
/// </summary>
public CSVLayer()
{
}

/// <summary>
/// Constructor for use in code
/// </summary>
/// <param name="url">
/// The url for the CSV source data.
/// </param>
/// <param name="title">
/// The title of the layer used to identify it in places such as the Legend and LayerList widgets.
/// </param>
/// <param name="copyright">
/// A copyright string to identify ownership of the data.
/// </param>
/// <param name="opacity">
/// The opacity of the layer.
/// </param>
/// <param name="visible">
/// Indicates if the layer is visible in the View. When false, the layer may still be added to a Map instance that is
/// referenced in a view, but its features will not be visible in the view.
/// </param>
/// <param name="listMode">
/// Indicates how the layer should display in the LayerList widget. The possible values are listed below.
/// </param>
public CSVLayer(string url, string? title = null, string? copyright = null,
double? opacity = null, bool? visible = null, ListMode? listMode = null)
{
#pragma warning disable BL0005
Url = url;
Title = title;
Comment on lines +52 to +53
Copy link
Collaborator

Choose a reason for hiding this comment

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

I realize this is missing in a lot of classes, including most layers, but we should wrap these parameter setters in #pragma warning disable BL0005. Search for that and you'll see some examples where I've implemented it. If you don't do this, and you create the class in C# with this constructor, you will get a warning about setting parameters outside of markup.

Opacity = opacity;
Visible = visible;
ListMode = listMode;
Copyright = copyright;
#pragma warning restore BL0005
}

/// <inheritdoc />
[JsonPropertyName("type")]
public override string LayerType => "csv";

/// <summary>
/// The url for the GeoRSS source data.
/// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Url { get; set; }

/// <summary>
/// A copyright string to identify ownership of the data.
/// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Copyright { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public GeoJSONLayer(string? url = null, string? copyright = null, string? title
Opacity = opacity;
Visible = visible;
ListMode = listMode;
Copyright = copyright;
}

/// <inheritdoc />
Expand Down
2 changes: 2 additions & 0 deletions src/dymaptic.GeoBlazor.Core/Components/Layers/Layer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ internal class LayerConverter : JsonConverter<Layer>
return JsonSerializer.Deserialize<OpenStreetMapLayer>(ref cloneReader, newOptions);
case "elevation":
return JsonSerializer.Deserialize<ElevationLayer>(ref cloneReader, newOptions);
case "csv":
return JsonSerializer.Deserialize<CSVLayer>(ref cloneReader, newOptions);
}
}

Expand Down
19 changes: 18 additions & 1 deletion src/dymaptic.GeoBlazor.Core/Scripts/arcGisJsInterop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import Layer from "@arcgis/core/layers/Layer";
import VectorTileLayer from "@arcgis/core/layers/VectorTileLayer";
import TileLayer from "@arcgis/core/layers/TileLayer";
import GeoJSONLayer from "@arcgis/core/layers/GeoJSONLayer";
import CSVLayer from "@arcgis/core/layers/CSVLayer";
import GeoRSSLayer from "@arcgis/core/layers/GeoRSSLayer";
import PopupTemplate from "@arcgis/core/PopupTemplate";
import Query from "@arcgis/core/rest/support/Query";
Expand Down Expand Up @@ -1966,7 +1967,7 @@ export async function createLayer(layerObject: any, wrap?: boolean | null, viewI
});
} else if (hasValue(layerObject.portalItem)) {
let portalItem = buildJsPortalItem(layerObject.portalItem);
openStreetMapLayer = new OpenStreetMapLayer({portalItem: portalItem});
openStreetMapLayer = new OpenStreetMapLayer({ portalItem: portalItem });
} else {
openStreetMapLayer = new OpenStreetMapLayer();
}
Expand Down Expand Up @@ -1997,6 +1998,22 @@ export async function createLayer(layerObject: any, wrap?: boolean | null, viewI
}
}

break;
case 'csv':
newLayer = new CSVLayer({
url: layerObject.url,
copyright: layerObject.copyright
});
let csvLayer = newLayer as CSVLayer;
if (hasValue(layerObject.renderer)) {
csvLayer.renderer = layerObject.renderer;
}
if (hasValue(layerObject.spatialReference)) {
csvLayer.spatialReference = new SpatialReference({
wkid: layerObject.spatialReference.wkid
});
}

break;
default:
return null;
Expand Down