Utilizando el más reciente SDK .net core de ESRI ArcGis en una aplicación local (no web).
Trato de crear una clase envolvente basada en ArcGis:IFeatureSet que tomará una colección de objetos que implementan IGeoCoordinate (Proporcionar un GeoCoordinate) y generará automáticamente todas las características y sus propiedades.
Todo parece posible y casi funciona pero no encuentro la forma de crear una Característica dando su polilínea y un conjunto de atributos.
¿Alguien sabe cómo crear una característica de forma programada?
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.UI;
using EsriUtil;
using GeoCoordinatePortable;
using GeoGraphicalCore;
using HQ.Util.General.Reflection;
using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;
namespace ElectricalNetworkMapArcgis.Util
{
public class FeatureSetWrapper<T> : IFeatureSet where T : IGeoCoordinateContainer // EO: It should already exists...
{
public IEnumerable<T> Objects { get; private set; }
public List<Feature> Features { get; private set; }
public List<Field> _fields { get; private set; }
public GeometryType GeometryType { get; private set; }
public SpatialReference SpatialReference { get; private set; }
public FeatureSetWrapper(IEnumerable<T> objects, GeometryType geometryType, SpatialReference spatialReference)
{
Objects = objects;
GeometryType = geometryType;
SpatialReference = spatialReference;
FillFieldsThroughReflection();
FillFeatures();
}
public void FillFieldsThroughReflection()
{
foreach(var prop in typeof(T).GetProperties())
{
if (prop.CanRead)
{
Field field = new Field(prop.PropertyType.GetEsriAssociatedFieldType(), prop.Name, prop.DisplayName(), GetEvaluatedFieldLenght(prop), null, prop.CanWrite, false);
_fields.Add(field);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="pi"></param>
/// <returns>The proper maxLenght if the count of items if less than "maxIteration" otherwise return a very rough estimate</returns>
int GetEvaluatedFieldLenght(PropertyInfo pi)
{
int stringLenghtMax = 0;
if (pi.PropertyType == typeof(string))
{
const int maxIteration = 60; // EO: ~random choice. IF there is millions of record, it would take too much time to verify all, considering also that is from reflection.
int iterCount = 0;
foreach(T obj in Objects)
{
stringLenghtMax = Math.Max(stringLenghtMax, pi.GetValue(obj).ToString().Length);
iterCount++;
if (iterCount == maxIteration) // Prevent potential super long delay
{
return stringLenghtMax * 2; // We reach maxIteration and estimate (hope we are right) to keep the double in order to give room for not evaluated values.
}
}
}
return stringLenghtMax;
}
/// <summary>
///
/// </summary>
/// <returns>Return the count of feature</returns>
int FillFeatures()
{
int countOfObject = 0;
var polyLineBuilder = new PolylineBuilder(SpatialReferences.Wgs84);
foreach (T obj in Objects)
{
IEnumerable<GeoCoordinate> geoCoordinates = obj.GetGeoCoordinates();
foreach (var geoCoordinate in geoCoordinates)
{
// EO: check is coordinates are into Quebec limits
Debug.Assert(geoCoordinate.Longitude > -80 && geoCoordinate.Longitude < -57);
Debug.Assert(geoCoordinate.Latitude > 44 && geoCoordinate.Latitude < 62);
MapPoint pointIter = new MapPoint(geoCoordinate.Longitude, geoCoordinate.Latitude, SpatialReferences.Wgs84);
polyLineBuilder.AddPoint(pointIter);
}
var polyline = polyLineBuilder.ToGeometry();
// For GraphicOverlay
// var graphic = new Graphic(polyline, _simpleLineSymbol);
// BUG HERE
var feature = new Feature(polyline); // DOES NOT EXISTS
// Add Attributes here
Features.Add(feature);
countOfObject++;
polyLineBuilder.Parts.Clear();
}
return countOfObject;
}
private static readonly SimpleLineSymbol _simpleLineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, System.Drawing.Color.FromArgb(128, 255, 0, 0), 2);
public IReadOnlyList<Field> Fields => _fields;
public IEnumerator<Feature> GetEnumerator()
{
return Features.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Features.GetEnumerator();
}
}
}