Преобразовать список Point3D в массив координат - PullRequest
2 голосов
/ 28 января 2012

Я использую NetTopologySuite для упрощения линий.

Проблема, с которой я сталкиваюсь, заключается в том, что у меня есть свой собственный класс, в котором хранится список Point3D (System.Windows.Media), а NetTopology имеет свой собственный класс Coordinate спочти те же свойства и функции.

Для преобразования списка point3D в координатный массив я использую эту функцию:

public static GeoApiInterfaces.ICoordinate[] ToCoordinateArray(this IEnumerable<Point3D> listToClone,
                                             bool isClosed = false)
{
  // if geometry is to be closed the size of array will be one more than the
  // current point count
  var coordinateList = new GeoApiInterfaces.ICoordinate[isClosed ?
                                                         listToClone.Count() + 1
                                                         : listToClone.Count()];

  // loop through all the point in the list to create the array
  int elementIndex = 0;
  foreach (var point in listToClone)
  {
    var coordinate = new GeoApiGeometries.Coordinate(point.X,
                                                    point.Y,
                                                    point.Z);

    coordinateList[elementIndex] = coordinate;
    elementIndex++;
  } // foreach

  // if geometry is closed the add the first point to the last
  if (isClosed)
  {
    var coordinate = new GeoApiGeometries.Coordinate(listToClone.ElementAt(0).X,
                                                    listToClone.ElementAt(0).Y,
                                                    listToClone.ElementAt(0).Z);

    coordinateList[elementIndex] = coordinate;
  } // if isClosed

  return coordinateList;
}

Все работает нормально, но когда я профилировал свой код почти 95% времениберется этой функцией.Мне интересно, есть ли другие способы преобразовать список System.Windows.Media.Point3D в Coordinate [].

То же самое будет верно для одного класса в другое преобразование.

Ответы [ 3 ]

1 голос
/ 28 января 2012

Обновление Если коллекция List<>, то мы можем сделать одноразовое отражение в базовом массиве, как это

static FieldInfo f_items = typeof(List<Point3D>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance);
static FieldInfo f_size = typeof(List<Point3D>).GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance);

и затем используйте его код каждый раз, когда мы хотим преобразовать как List<Point3D> в Point3D, как это

Point3D[] array = f_items.GetValue(list) as Point3D[];
int size= (int)f_size.GetValue(list);

Тогда вы можете продолжить с кодом ниже. Если коллекции IEnumerable<> - это что-то другое, вам нужно сначала выяснить, как элементы хранятся внутри.

Оригинал

Я думаю, что если вы можете ограничить себя массивами вместо IEnumerable<>, тогда вы сможете достичь более высоких скоростей.

Вот пример кода, который является компактным и должен работать как можно быстрее.

public struct Point3D
{
    public double x, y, z;        
}

public static class Extensions
{
    public static ICoordinate[] ToCoord(this Point3D[] points, int size)
    {
        size = Math.Min(points.Length,size); //make sure there are enough points
        ICoordinate[] res = new ICoordinate[size];
        for (int i = 0; i < size; i++)
        {
            res[i] = new Coordinate(points[i].x, points[i].y, points[i].z);
        }
        return res;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Point3D[] array1 = new Point3D[N];
        // Fill the array ..
        ICoordinate[] array2 = array1.ToCoord();
    }
}
0 голосов
/ 13 февраля 2012

Я вызывал эту функцию, поскольку она заменяет эту функцию, и она повышает производительность.Я должен был опубликовать весь код.

0 голосов
/ 28 января 2012

Нет способа сделать этот метод быстрее. Вы можете буферизовать listToClone.ElementAt (0) в последнем блоке, но это вряд ли имеет отношение к общей производительности с длинными списками.

Если исходные и целевые координаты были эквивалентными типами значений, вы можете попробовать трюки с указателями, чтобы напрямую скопировать их данные. Но, к сожалению, GeoApiGeometries.Coordinate является ссылочным типом, предположительно потому, что библиотека была портирована с Java, поэтому вам обязательно нужно выделять каждый новый элемент вручную, как вы это делаете сейчас.

...