Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fa554f8
Bump lodash-es from 4.17.22 to 4.18.1 in /src/dymaptic.GeoBlazor.Core
dependabot[bot] Jun 10, 2026
cc8caed
Bump flatted from 3.3.3 to 3.4.2 in /src/dymaptic.GeoBlazor.Core
dependabot[bot] Jun 10, 2026
fda0bbf
Bump minimatch, eslint, eslint-plugin-sonarjs and typescript-eslint
dependabot[bot] Jun 10, 2026
fc9d07a
Merge main into develop before release
TimPurdum Jun 10, 2026
b01d215
Bump esbuild from 0.27.1 to 0.28.1 in /src/dymaptic.GeoBlazor.Core
dependabot[bot] Jun 14, 2026
749cbf6
Restore SnappingOptions runtime setters (4.5.x regression)
magmoe Jun 17, 2026
71437ba
Add Union/Extent regression guards
magmoe Jun 17, 2026
55a93a5
Pipeline Build Commit of Version and Docs
submodule-validation-for-geoblazor[bot] Jun 17, 2026
ad7862f
Expand SnappingOptions API contract test to the full surface
magmoe Jun 17, 2026
fd74d3f
Pipeline Build Commit of Version and Docs
submodule-validation-for-geoblazor[bot] Jun 17, 2026
c5f7b16
Populate geometry Extent for operator results (Union extent regression)
TimPurdum Jun 17, 2026
3de5fad
Pipeline Build Commit of Version and Docs
submodule-validation-for-geoblazor[bot] Jun 17, 2026
a02d701
Bump protobufjs from 7.5.8 to 7.6.3 in /src/dymaptic.GeoBlazor.Core
dependabot[bot] Jun 19, 2026
fe23867
Include Z/M bounds in calculated extent fallback
TimPurdum Jun 19, 2026
ebe16be
Pipeline Build Commit of Version and Docs
submodule-validation-for-geoblazor[bot] Jun 19, 2026
0f42a87
Compute missing geometry extent via ArcGIS instead of C# logic
TimPurdum Jun 19, 2026
c000659
Pipeline Build Commit of Version and Docs
submodule-validation-for-geoblazor[bot] Jun 19, 2026
d57792f
Merge branch 'develop' into fix/snapping-options-setters
TimPurdum Jun 19, 2026
8502e15
Merge pull request #530 from dymaptic/fix/snapping-options-setters
TimPurdum Jun 19, 2026
838c855
Merge branch 'develop' into dependabot/npm_and_yarn/src/dymaptic.GeoB…
TimPurdum Jun 19, 2026
dff2c21
Merge pull request #526 from dymaptic/dependabot/npm_and_yarn/src/dym…
TimPurdum Jun 19, 2026
8239bdb
Merge pull request #527 from dymaptic/dependabot/npm_and_yarn/src/dym…
TimPurdum Jun 19, 2026
ea0c0c3
Merge branch 'develop' into dependabot/npm_and_yarn/src/dymaptic.GeoB…
TimPurdum Jun 19, 2026
0bab2f1
Merge pull request #528 from dymaptic/dependabot/npm_and_yarn/src/dym…
TimPurdum Jun 19, 2026
b79493e
Merge branch 'develop' into dependabot/npm_and_yarn/src/dymaptic.GeoB…
TimPurdum Jun 19, 2026
bae6c5a
Merge pull request #529 from dymaptic/dependabot/npm_and_yarn/src/dym…
TimPurdum Jun 19, 2026
978074d
Merge pull request #531 from dymaptic/dependabot/npm_and_yarn/src/dym…
TimPurdum Jun 19, 2026
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
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<CoreVersion>4.5.2</CoreVersion>
<CoreVersion>4.5.2.5</CoreVersion>
<Configurations>Debug;Release;SourceGen Highlighting</Configurations>
<Platforms>AnyCPU</Platforms>
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public Polygon(
public override GeometryType Type => GeometryType.Polygon;

#endregion

/// <summary>
/// Returns a deep clone of the geometry.
/// </summary>
Expand Down
309 changes: 309 additions & 0 deletions src/dymaptic.GeoBlazor.Core/Components/SnappingOptions.gb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,315 @@ public SnappingOptions(
return SelfEnabled;
}

#endregion

#region Property Setters

/// <summary>
/// Asynchronously set the value of the AttributeRulesEnabled property after render.
/// </summary>
/// <param name="value">
/// The value to set.
/// </param>
public async Task SetAttributeRulesEnabled(bool? value)
{
#pragma warning disable BL0005
AttributeRulesEnabled = value;
#pragma warning restore BL0005
ModifiedParameters[nameof(AttributeRulesEnabled)] = value;

if (CoreJsModule is null)
{
return;
}

try
{
JsComponentReference ??= await CoreJsModule.InvokeAsync<IJSObjectReference?>(
"getJsComponent", CancellationTokenSource.Token, Id);
}
catch (JSException)
{
// this is expected if the component is not yet built
}

if (JsComponentReference is null)
{
return;
}

await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token,
JsComponentReference, "attributeRulesEnabled", value);
}

/// <summary>
/// Asynchronously set the value of the Distance property after render.
/// </summary>
/// <param name="value">
/// The value to set.
/// </param>
public async Task SetDistance(double? value)
{
#pragma warning disable BL0005
Distance = value;
#pragma warning restore BL0005
ModifiedParameters[nameof(Distance)] = value;

if (CoreJsModule is null)
{
return;
}

try
{
JsComponentReference ??= await CoreJsModule.InvokeAsync<IJSObjectReference?>(
"getJsComponent", CancellationTokenSource.Token, Id);
}
catch (JSException)
{
// this is expected if the component is not yet built
}

if (JsComponentReference is null)
{
return;
}

await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token,
JsComponentReference, "distance", value);
}

/// <summary>
/// Asynchronously set the value of the Enabled property after render.
/// </summary>
/// <param name="value">
/// The value to set.
/// </param>
public async Task SetEnabled(bool? value)
{
#pragma warning disable BL0005
Enabled = value;
#pragma warning restore BL0005
ModifiedParameters[nameof(Enabled)] = value;

if (CoreJsModule is null)
{
return;
}

try
{
JsComponentReference ??= await CoreJsModule.InvokeAsync<IJSObjectReference?>(
"getJsComponent", CancellationTokenSource.Token, Id);
}
catch (JSException)
{
// this is expected if the component is not yet built
}

if (JsComponentReference is null)
{
return;
}

await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token,
JsComponentReference, "enabled", value);
}

/// <summary>
/// Asynchronously set the value of the FeatureEnabled property after render.
/// </summary>
/// <param name="value">
/// The value to set.
/// </param>
public async Task SetFeatureEnabled(bool? value)
{
#pragma warning disable BL0005
FeatureEnabled = value;
#pragma warning restore BL0005
ModifiedParameters[nameof(FeatureEnabled)] = value;

if (CoreJsModule is null)
{
return;
}

try
{
JsComponentReference ??= await CoreJsModule.InvokeAsync<IJSObjectReference?>(
"getJsComponent", CancellationTokenSource.Token, Id);
}
catch (JSException)
{
// this is expected if the component is not yet built
}

if (JsComponentReference is null)
{
return;
}

await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token,
JsComponentReference, "featureEnabled", value);
}

/// <summary>
/// Asynchronously set the value of the FeatureSources property after render.
/// </summary>
/// <param name="value">
/// The value to set.
/// </param>
public async Task SetFeatureSources(IReadOnlyList<FeatureSnappingLayerSource>? value)
{
if (value is not null)
{
foreach (FeatureSnappingLayerSource item in value)
{
item.UpdateGeoBlazorReferences(CoreJsModule!, ProJsModule, View, this, Layer);
}
}

#pragma warning disable BL0005
FeatureSources = value;
#pragma warning restore BL0005
ModifiedParameters[nameof(FeatureSources)] = value;

if (CoreJsModule is null)
{
return;
}

try
{
JsComponentReference ??= await CoreJsModule.InvokeAsync<IJSObjectReference?>(
"getJsComponent", CancellationTokenSource.Token, Id);
}
catch (JSException)
{
// this is expected if the component is not yet built
}

if (JsComponentReference is null)
{
return;
}

await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token,
JsComponentReference, "featureSources", value);
}

/// <summary>
/// Asynchronously set the value of the GridEnabled property after render.
/// </summary>
/// <param name="value">
/// The value to set.
/// </param>
public async Task SetGridEnabled(bool? value)
{
#pragma warning disable BL0005
GridEnabled = value;
#pragma warning restore BL0005
ModifiedParameters[nameof(GridEnabled)] = value;

if (CoreJsModule is null)
{
return;
}

try
{
JsComponentReference ??= await CoreJsModule.InvokeAsync<IJSObjectReference?>(
"getJsComponent", CancellationTokenSource.Token, Id);
}
catch (JSException)
{
// this is expected if the component is not yet built
}

if (JsComponentReference is null)
{
return;
}

await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token,
JsComponentReference, "gridEnabled", value);
}

/// <summary>
/// Asynchronously set the value of the SelfEnabled property after render.
/// </summary>
/// <param name="value">
/// The value to set.
/// </param>
public async Task SetSelfEnabled(bool? value)
{
#pragma warning disable BL0005
SelfEnabled = value;
#pragma warning restore BL0005
ModifiedParameters[nameof(SelfEnabled)] = value;

if (CoreJsModule is null)
{
return;
}

try
{
JsComponentReference ??= await CoreJsModule.InvokeAsync<IJSObjectReference?>(
"getJsComponent", CancellationTokenSource.Token, Id);
}
catch (JSException)
{
// this is expected if the component is not yet built
}

if (JsComponentReference is null)
{
return;
}

await CoreJsModule.InvokeVoidAsync("setProperty", CancellationTokenSource.Token,
JsComponentReference, "selfEnabled", value);
}

#endregion

#region Add to Collection Methods

/// <summary>
/// Asynchronously adds elements to the FeatureSources property.
/// </summary>
/// <param name="values">
/// The elements to add.
/// </param>
public async Task AddToFeatureSources(params FeatureSnappingLayerSource[] values)
{
FeatureSnappingLayerSource[] join = FeatureSources is null
? values
: [..FeatureSources, ..values];
await SetFeatureSources(join);
}

#endregion

#region Remove From Collection Methods


/// <summary>
/// Asynchronously remove an element from the FeatureSources property.
/// </summary>
/// <param name="values">
/// The elements to remove.
/// </param>
public async Task RemoveFromFeatureSources(params FeatureSnappingLayerSource[] values)
{
if (FeatureSources is null)
{
return;
}
await SetFeatureSources(FeatureSources.Except(values).ToArray());
}

#endregion


Expand Down
36 changes: 33 additions & 3 deletions src/dymaptic.GeoBlazor.Core/Scripts/geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,50 @@ export function buildDotNetGeometry(geometry: any): any {
if (!hasValue(geometry)) {
return null;
}
let dotNetGeometry: any;
switch (geometry?.type) {
case "point":
return buildDotNetPoint(geometry);
case "polyline":
return buildDotNetPolyline(geometry);
dotNetGeometry = buildDotNetPolyline(geometry);
break;
case "polygon":
return buildDotNetPolygon(geometry);
dotNetGeometry = buildDotNetPolygon(geometry);
break;
case "extent":
return buildDotNetExtent(geometry);
case "multipoint":
return buildDotNetMultipoint(geometry);
dotNetGeometry = buildDotNetMultipoint(geometry);
break;
case "mesh":
return buildDotNetMesh(geometry);
default:
return undefined;
}

// Geometries returned from the operator API (e.g. unionOperator) do not always expose
// a cached `extent`, which previously left the .NET Geometry.Extent null (breaking
// e.g. view.GoTo(extent)). Use ArcGIS to compute a missing extent.
if (hasValue(dotNetGeometry) && !hasValue(dotNetGeometry.extent)) {
let jsExtent = getArcGisExtent(geometry, dotNetGeometry);
if (hasValue(jsExtent)) {
dotNetGeometry.extent = buildDotNetExtent(jsExtent);
}
}

return dotNetGeometry;
}

// Returns the ArcGIS-computed extent for a geometry. Prefers the geometry's own `.extent`
// (computed lazily by the SDK, including Z/M bounds); when an operator result doesn't
// expose one, rebuilds a typed ArcGIS geometry from the same coordinates so the SDK
// recomputes it, rather than calculating the bounding box by hand.
function getArcGisExtent(geometry: any, dotNetGeometry: any): any {
if (hasValue(geometry?.extent)) {
return geometry.extent;
}
let rebuilt = buildJsGeometry(dotNetGeometry);
return rebuilt?.extent ?? null;
}

export function buildJsGeometry(geometry: any): any {
Expand Down
Loading
Loading