Filtraggio e indicizzazione di layer vettoriali GIS in C#

Con Aspose.GIS per .NET puoi filtrare i layer in base ai valori degli attributi o ai limiti spaziali. Puoi anche usare gli indici per velocizzare il filtraggio e le query spaziali.

Indice degli attributi

Filtro senza indice

Ecco come filtrare un layer in base ai valori di un attributo:

// For complete examples and data files, please go to https://github.com/aspose-gis/Aspose.GIS-for-.NET
using (var layer = VectorLayer.Open(citiesPath, Drivers.GeoJson))
{
// Select features based on values of the attribute. This code enumerates all features in the layer
// and selects all features that match a condition.
var features = layer.WhereGreaterOrEqual("population", 2000).WhereSmaller("population", 5000);
// Print results.
Console.WriteLine("Cities where population >= 2000 and population < 5000:");
foreach (var feature in features)
{
var name = feature.GetValue<string>("name");
var population = feature.GetValue<int>("population");
Console.WriteLine(name + ", " + population);
}
Console.WriteLine();
}

Filtro con indice

Il codice precedente va bene finché il layer viene filtrato solo una volta. Ma, se il layer è suscettibile di essere interrogato più volte, possiamo beneficiare degli indici degli attributi. Richiede un po' di tempo per costruire l’indice degli attributi, ma può essere riutilizzato più volte per accelerare il filtraggio.

Il seguente esempio utilizza un file di indice degli attributi per velocizzare il filtraggio del layer in base ai valori dell’attributo:

// For complete examples and data files, please go to https://github.com/aspose-gis/Aspose.GIS-for-.NET
using (var layer = VectorLayer.Open(citiesPath, Drivers.GeoJson))
{
// Use attribute index to speed up search by 'population' attribute.
// Aspose.GIS builds a new index if it doesn't exist, otherwise existing index is reused.
// Any path can be used.
var attributeIndexPath = Path.ChangeExtension(citiesPath, "population_out.ix");
layer.UseAttributesIndex(attributeIndexPath, "population");
// Select features based on values of the attribute. Since we use attribute index it is not necessary to
// test all features of the layer and filtering time is reduced significantly.
var towns = layer.WhereGreaterOrEqual("population", 2000).WhereSmaller("population", 5000);
// Print results.
Console.WriteLine("Cities where population >= 2000 and population < 5000:");
foreach (var town in towns)
{
var name = town.GetValue<string>("name");
var population = town.GetValue<int>("population");
Console.WriteLine(name + ", " + population);
}
Console.WriteLine();
}

Salva le funzionalità filtrate

Le funzionalità filtrate possono essere salvate nei layer:

// For complete examples and data files, please go to https://github.com/aspose-gis/Aspose.GIS-for-.NET
using (var layer = VectorLayer.Open(citiesPath, Drivers.GeoJson))
{
// Use attribute index to speed up search by 'population' attribute.
var attributeIndexPath = Path.ChangeExtension(citiesPath, "population_out.ix");
layer.UseAttributesIndex(attributeIndexPath, "population");
// Save all features with population between 2000 and 5000 to the output file.
layer.WhereGreaterOrEqual("population", 2000)
.WhereSmaller("population", 5000)
.SaveTo(DataDir + "towns_out.shp", Drivers.Shapefile);
}

Renderizza le funzionalità filtrate

È anche possibile renderizzare le funzionalità filtrate. Il seguente esempio utilizza l’indice degli attributi per selezionare rapidamente tutte le funzionalità con una popolazione superiore a 2000 e aggiungerle alla mappa:

// For complete examples and data files, please go to https://github.com/aspose-gis/Aspose.GIS-for-.NET
using (var map = new Map(600, 400))
using (var cities = VectorLayer.Open(citiesPath, Drivers.GeoJson))
{
map.Padding = 20;
// Use attribute index to speed up search by 'population' attribute.
var attributeIndexPath = Path.ChangeExtension(citiesPath, "population_out.ix");
cities.UseAttributesIndex(attributeIndexPath, "population");
// Render all cities with population greater than 2000.
map.Add(cities.WhereGreater("population", 2000), new SimpleMarker { FillColor = Color.Red });
map.Render(outputPath, Renderers.Svg);
}

Indice spaziale

Gli indici spaziali vengono utilizzati per accelerare le query spaziali. Proprio come gli indici degli attributi, gli indici spaziali vengono riutilizzati dopo la creazione.

Trova le funzionalità più vicine a un punto

Ecco come utilizzare l’indice spaziale per velocizzare la ricerca della funzionalità più vicina a un determinato punto:

// For complete examples and data files, please go to https://github.com/aspose-gis/Aspose.GIS-for-.NET
using (var layer = VectorLayer.Open(path, Drivers.GeoJson))
{
// Use spatial index to speed up spatial queries.
// Aspose.GIS builds a new index if it doesn't exist, otherwise existing index is reused.
// Any path can be used.
var spatialIndexPath = Path.ChangeExtension(path, ".spatial_out.ix");
layer.UseSpatialIndex(spatialIndexPath);
var point = new Point(12.30, 50.33);
// Since we use spatial index, nearest-to finds the closest feature much faster.
var nearest = layer.NearestTo(point);
Console.WriteLine("City nearest to (12.30 50.33) is " + nearest.GetValue<string>("name"));
Console.WriteLine();
}

Seleziona le funzionalità che intersecano con una geometria

Il seguente esempio utilizza l’indice spaziale per velocizzare la selezione delle funzionalità che intersecano una geometria:

// For complete examples and data files, please go to https://github.com/aspose-gis/Aspose.GIS-for-.NET
using (var layer = VectorLayer.Open(path, Drivers.GeoJson))
{
// Use spatial index to speed up 'WhereIntersects'.
var spatialIndexPath = Path.ChangeExtension(path, ".spatial_out.ix");
layer.UseSpatialIndex(spatialIndexPath);
var polygon = Geometry.FromText("Polygon((12.30 50.33, 22.49 54.87, 21.92 42.53, 12.30 50.33))");
var intersecting = layer.WhereIntersects(polygon);
Console.WriteLine("Cities within " + polygon.AsText() + ":");
foreach (var feature in intersecting)
{
var name = feature.GetValue<string>("name");
var location = (IPoint) feature.Geometry;
Console.WriteLine($"{name} at ({location.X}, {location.Y})");
}
Console.WriteLine();
}