вибір відсотка (75%) групи балів, виходячи з відстані від однієї окремої точки в ArcGIS?


9

Це специфічно для ArcGIS.

У мене є 2-х точкових форм-файлів, Aі Bперший ( A) - це одна точка, яка містить lat довгу, друга ( B) - це безліч точок (понад 12 к), кожен з яких містить свій lat і long. Що я намагаюся зробити, це автоматизувати вибір 75% Bточок формфайлу на основі відстані від формфайлу A. Іншими словами, я хочу вибрати найближчу 75% Bточок формфайлу Aдо однієї точки.


Чи прийнятне програмне рішення?
Кірк Куйкендалл

До речі, я просив Esri дозволити використовувати Shapefield у користувальницькому ITableSortCallback, але мені сказали, що для цього немає жодного обґрунтування. Цей випадок використання показує інше.
Кірк Куйкендалл

@Kirk Kuykendall Так, програмне рішення насправді було б кращим, оскільки це процес, який мені доведеться повторювати понад 1 к. Разів. У мене приблизно 1200 окремих точок, і кожна з цих точок має ще один профіль форми, в середньому 12 к. Пунктів навколо нього. Мені потрібно знайти спосіб легко вибрати найближчі 75% навколишніх точок для всіх. Робити це вручну, просто не виникає сумніву.
Фурлонг

Можливо, цей коментар виходить за межі належного коментування коментаря, але коли і чому такий аналіз буде корисним? Це для мого власного з'ясування; пробач мою повільність
Нафан

1
Подумайте про використання статистичного програмного забезпечення. Якщо ви мали б об'єднати всі 1200 файлів форм, створюючи поле ідентифікатора джерела під час злиття, ви можете приєднати до цього відповідні координати центральної точки і обчислити всі 1200 * 12k = 14.4M відстаней. Тоді вам знадобиться список 75-ти відсотків відстані за ідентифікатором джерела: це займе близько десяти секунд із Stata (комерційний) або R (відкритий код). (Якщо ви використовуєте для цього ArcGIS, повідомте нам, скільки часу потрібно на обчислення. :-)
whuber

Відповіді:


5

Ви можете зробити декілька кільцевих буферів у форміfile A, а потім виконати просторове з'єднання буфера з shapefile B. Коли ви зробите просторове з'єднання полігонів і точок, ви отримаєте підрахунок кількості точок у кожному многокутнику в атрибуті. таблиця приєднання. Потім, вивчивши загальну кількість балів у буферах, ви можете отримати в межах 75% балів у форміфайлу B.

Трохи іншим підходом буде сценарій цього в Python і перевірка 75% в циклі, але якщо це одноразовий розрахунок, можливо, вам це не знадобиться.


4
Було б простіше, швидше і точніше виконати просторове з'єднання від А до В, обчислити третій чверть результуючого поля [відстань] і вибрати всі записи, менші за цю відстань.
whuber

Я не знав, що можна просторово об’єднати бали! Я погоджуюся, це був би набагато кращий спосіб зробити це.
djq

@Andy Навпаки, з'єднання є відношенням найближчої точки. Він взагалі не заснований на будь-яких табличних атрибутах. Також у програмному забезпеченні Arc * (повертаючись до ArcView 2) відстань автоматично обчислюється в результаті з'єднання.
whuber

1
@whuber, я знаю! Звідси вилучене (видалене твердження!) Я припускаю, що ви могли це зробити, приєднуючись таблицю атрибутів (і самостійно обчислюючи відстань), але це було б непотрібно з огляду на контекст. Я думаю, що я хотів би ще раз зазначити, що це просто обчислення відстані між 1 точкою, ніяких циклів чи буферів чи ітеративних процедур не потрібно.
Енді Ш

1
@Furlong Якщо ви читаєте приклад просторового приєднання : help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//…, ви можете отримати уявлення про те, як запустити це в python. Тоді справа в тому, щоб
проглянути

4

Для 1200 крапок (або навіть до точки сказати 12M?) Я просто поклав їх в пам'яті як Generic Collection - в цьому випадку SortedList з списків . Це може бути спрощено просто пропускаючи точки, коли ви стикаєтесь із ситуацією з декількома точками, що знаходяться на однаковій відстані від точки початку. Також для продуктивності розгляньте використання хештеля замість SortedList та сортування один раз після вставки всіх відстаней. Це займе ще кілька рядків коду (?).

Я не встиг це перевірити, але цей c # може вас почати:

private void SelectNTile(string layer1, string layer2, double nTile)
{
    var fLayer1 = FindLayer(ArcMap.Document.FocusMap, "LayerWithLotsofPoints");
    var fLayer2 = FindLayer(ArcMap.Document.FocusMap, "LayerWithOneSelectedPoint");
    IFeature feat = GetSingleFeature(fLayer2);
    var distList = MakeDistList(fLayer1.FeatureClass,(IPoint)feat.ShapeCopy);
    // assume not many points exactly same distance
    var nRecs = (int)(distList.Count * nTile); // nTile would be 0.75 for 75%
    var Oids = new List<int>();
    foreach (KeyValuePair<double, List<int>> kvp in distList)
    {
        Oids.AddRange(kvp.Value);
        if (Oids.Count > nRecs)
            break;
    }
    var fSel = fLayer1 as IFeatureSelection;
    var OidArray = Oids.ToArray();
    fSel.SelectionSet.AddList(Oids.Count, ref OidArray[0]);                
}

private SortedList<double, List<int>> MakeDistList(IFeatureClass fc, IPoint pnt)
{
    var outList = new SortedList<double, List<int>>();
    var proxOp = pnt as IProximityOperator;
    IFeatureCursor fCur = null;
    try
    {
        fCur = fc.Search(null, true); // recycling is faster, we just need OIDs
        IFeature feat;
        while ((feat = fCur.NextFeature()) != null)
        {
            double dist = proxOp.ReturnDistance(feat.Shape);
            if (!outList.ContainsKey(dist))
                outList.Add(dist, new List<int> { feat.OID });
            else
                outList[dist].Add(feat.OID);  // this should rarely happen
        }
    }
    catch
    {
        throw;
    }
    finally
    {
        if (fCur != null)
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(fCur);
    }
    return outList;
}
private IFeature GetSingleFeature(IFeatureLayer fLayer)
{
    var fSel = fLayer as IFeatureSelection;
    if (fSel.SelectionSet.Count != 1)
        throw new Exception("select one feature in " + fLayer.Name + " first");
    var enumIDs = fSel.SelectionSet.IDs;
    enumIDs.Reset();
    IFeature feat = fLayer.FeatureClass.GetFeature(enumIDs.Next());
    return feat;
}
private IFeatureLayer FindLayer(IMap map, string name)
{
    throw new NotImplementedException();
}

4

Сценарій геообробки Python - очевидний вибір:

  1. Використовуйте інструмент « Відстань точки », щоб обчислити відстань від ваших функцій класу характеристик В (параметр «Вхідні функції» інструменту) до точки класу характеристик А (параметр «Поруч з функціями» інструменту).
  2. Сортуйте таблицю за розрахунковою відстані.
  3. Виберіть перші 75% об’єктів у таблиці виводу (стовпець "Вхідні_ФІД") і використовуйте їх для вибору з оригінальних функцій класу функцій B.

2

У мене це питання було кілька років тому. Мені було легше зберігати дані як "плоскі дані", перебираючи всі дані та обчислюючи відстань вручну, потім взявши верхню 75% (я фактично зберігала перші 10%). Потім я зробив те саме в ArcIMS, використовуючи їх розрахунки відстані, і це зайняло набагато більше часу.

Буферизація - це величезна накладні витрати, але математичні розрахунки - це "фортеця". Якщо у вас буфер 12k балів, я думаю, у вас виникнуть проблеми з виконанням.


Я [@Mapperz] видалив коментарі - вказівки щодо модних інструментів позначили цю публікацію, тому що вона погіршилась у безглузді
переплетіння
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.