根据到ArcGIS中一个单独点的距离选择一组点的百分比(75%)?


9

这是特定于ArcGIS的。

我有2个点shapefile,A并且B,第一个(A)是包含lat long的单个点,第二个(B)是多个点(超过12k),每个点都包含其lat和long。我要做的是B根据距shapefile的距离自动选择shapefile 点的75%A。换句话说,我想选择最接近shapefile B点的75%到shapefile A的一个点。


程序解决方案可以接受吗?
柯克·库肯达尔

顺便说一句,我要求Esri允许在自定义ITableSortCallback中使用Shapefield,但被告知没有理由。此用例另有说明。
Kirk Kuykendall,

@Kirk Kuykendall是的,实际上会首选程序化解决方案,因为这是我必须重复执行1000次以上的过程。我大约有1200个单独的点,并且每个点都有另一个shapefile,其周围平均有1.2万个点。我需要找出一种方法轻松地为所有这些点选择最接近的75%的周围点。手动进行操作是不可能的。
福隆

也许此评论不在评论的适当范围之内,但是这种分析何时,为什么有用?这是出于我自己的解释;原谅我的缓慢。
纳撒努斯2011年

1
考虑使用统计软件。如果要合并所有1200个shapefile,并在合并过程中创建一个源id字段,则可以将相应的中心点坐标与之合并,并计算所有1200 * 12k = 14.4M的距离。然后,您需要的是按源ID列出距离的第75个百分点:使用Stata(商业)或R(开源)大约需要十秒钟。(如果您为此使用ArcGIS,请让我们知道计算需要多少时间。:-)
whuber

Answers:


5

您可以在shapefile A上创建一个多环缓冲区,然后对Buffer和shapefile B进行空间连接。当您进行多边形和点的空间连接时,您将获得属性中每个多边形的点数计数联接表。然后,通过检查缓冲区中的点总数,可以得到shapefile B中点的75%以内。

稍有不同的方法是使用Python编写脚本,并在循环中检查75%,但是如果它是一次性计算,则可能不需要。


4
执行A与B的空间连接,计算所得的[距离]字段的第三个四分位数,并选择所有小于该距离的记录,将更加简单,快捷且准确。
Whuber

我不知道在空间上可以合并点!我同意,这将是更好的方法。
djq 2011年

@Andy相反,联接是最近点关系。它根本不基于任何列表属性。同样,在Arc *软件中(返回到ArcView 2),距离是作为连接结果自动计算的。
ub

1
@whuber,我知道!因此,缩进(删除的语句!)我假设您可以通过属性表联接(并自己计算距离)来做到这一点,但这在上下文中是不必要的。我想重申的一点是,它只是计算1点之间的距离,不需要循环或缓冲区或迭代过程。
安迪W

1
@Furlong如果您阅读了Spatial Join的示例:help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//…,您将获得一个如何在python中运行它的想法。然后,它通过属性表的运行环境及符合条件的值的问题
DJQ

4

对于1200点(甚至高达12M说点?)我只是把它们到内存中泛型集合-在这种情况下,排序列表列出。当您遇到到多个与原点距离相同的点的情况时,可以通过跳过这些点来简化此操作。另外,为了提高性能,请考虑使用哈希表而不是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. 使用“ 点距离”工具计算从要素类B中的要素(该工具的“输入要素”参数)到要素类A中的点(该工具的“近要素”参数)的距离。
  2. 按计算出的距离对表格进行排序。
  3. 在输出表(“ Input_FID”列)中选择前75%的对象ID,然后使用这些对象从要素类B中的原始要素中进行选择。

2

几年前,我遇到了这个问题。我发现更容易将数据保留为“平面数据”,遍历所有数据并手动计算距离,然后选择最高的75%(实际上我保留了最高的10%)。然后,我使用他们的距离计算在ArcIMS中进行了相同的操作,并且花费了更长的时间。

缓冲是一个巨大的开销,但是数学计算是“长篇大论”。如果您缓冲12k点,我认为您将遇到性能问题。


我[@Mapperz]删除了评论-mod工具指南将该帖子标记为该帖子,因为它降级为毫无意义的争吵...
Mapperz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.