如何在iOS中获取缓冲区多边形坐标(纬度和经度)?

如何在iOS中获取缓冲区多边形坐标(纬度和经度)?,ios,swift,coordinates,polygon,arcgis,Ios,Swift,Coordinates,Polygon,Arcgis,我在地图上用一些坐标创建了一个多边形。 我需要帮助,使一个缓冲多边形与一些给定的距离以外的原始多边形边界 所以我需要一种算法,在这种算法中,我传递一组坐标作为输入,应该得到一组缓冲坐标作为输出 我试图通过使用arcgis library for ios和AGSGeometryEngine的bufferGeometry方法来实现这一点,但问题是,这是紧密耦合的,只能使用他们的GIS地图,但我使用的是不同地图的Mapbox。所以我想要一个通用的方法,它可以独立于map来解决我的问题 < P>看看

我在地图上用一些坐标创建了一个多边形。 我需要帮助,使一个缓冲多边形与一些给定的距离以外的原始多边形边界

所以我需要一种算法,在这种算法中,我传递一组坐标作为输入,应该得到一组缓冲坐标作为输出

我试图通过使用arcgis library for ios和AGSGeometryEngine的bufferGeometry方法来实现这一点,但问题是,这是紧密耦合的,只能使用他们的GIS地图,但我使用的是不同地图的Mapbox。所以我想要一个通用的方法,它可以独立于map来解决我的问题

< P>看看这是一个大的C++库,你可以找到几乎所有的库/源代码,比如不同类型的缓冲方法,如斜切、圆、正方形等。 只需安装Boost的最新版本,我猜现在是1.58.0,看看Boost/Geometry/Strategies/Cartesian/buffer[Something]-Square/Miter/Round

这是一个好主意


您需要将大地坐标(lat/long)转换为笛卡尔坐标(x/y),使用Boost库并反转转换。您根本不需要使用ArcGIS或任何其他GIS库

我的应用程序中也有同样的问题,最后在

我是一名android开发人员,我的代码可能对您没有用处,但核心概念是相同的

  • 首先,我们需要借助两点定位点来确定直线的方位。(我使用了计算距离和方位(双lat1、双lon1、双lat2、双lon2)函数)
  • 现在,为了得到某个点的缓冲,我们需要给出缓冲距离、LatLng点和方位(我从计算距离和方位函数中获得)。(我使用计算距离和方位(双lat1、双lon1、双brng、双dist)函数来实现这一点)。从一个车床点开始,我们通过使它们的轴承保持一定距离来得到两个点
  • 现在我们需要找到两点的兴趣点来得到我们想要的缓冲。为此,请记住获取另一条线的新点和方向角,并与另一条线相同。这有助于通过所需的缓冲获得新的交点。(我已在我的函数computeIntersectionPoint(LatLng p1、double brng1、LatLng p2、double brng2)中完成了这一操作。
  • 对所有多边形点执行此操作,然后获得新的点,这些点与您的关节相连以获得缓冲
  • 这就是我在我的android位置应用程序whis中所做的

    这是我的密码 //计算距离和轴承(双车床1,双lon1, 双拉特2,双拉特2)

    //计算交叉点(板条p1、双brng1、板条p2、双brng2)

    我会建议你通过上述网站,并获得知识,因为我也做了同样的事情

    希望这能有所帮助,我知道ios中没有,但这个概念与我通过更改javascript代码完成项目时的概念相同


    干杯

    我的要求与此类似。我最终为此编写了自己的算法。
    您只需使用这一行即可

    double distance = 0.0001;
    List bufferedPolygonList = AreaBuffer.buffer(pointList, distance);
    
    它提供了一个缓冲多边形点列表,这些点与原始多边形之间的距离为给定的。

    我建议使用Turf.js库进行缓冲和许多基本的gis操作。您将能够从返回的路径中检索每条边。对于geometry buffer,它很容易使用,重量很轻,对于使用MapBox.js或传单的应用程序来说,它不会有任何问题。
    更多详情:


    但若你们正在寻找一个测地距离缓冲区,那个可能是个问题。我将使用Arcgis Javascript API

    更新您的问题,说明您迄今为止所做的工作以及您所做的尝试。解释您需要的具体帮助。@rmaddy:在大多数不同的地图API中,都有用于绘制多边形的方法,我们只需传递lat和long坐标数组,其余部分由这些函数负责,但在这里,我需要一个通用算法,该算法将在考虑给定缓冲坐标坐标的情况下执行。这是我在Mapbox API中找不到的。问题用swift标记。不客观c@Ccr无所谓,使用Swift和Objtovi-C中的C++库是非常常见的,在大型项目中是不可避免的。而对于记录,它不是ObjuleC,它是C++库。@ Zig如Ccr所指出的,你不能(很容易)在iOS上使用C++绘图方法。正确的方法是CoreGraphics或类似的方法。嘿,Ravikant,我试图使用这个解决方案,但有点陷入第三点。您能否提供更多关于在函数computeIntersectionPoint中传递什么的详细信息。在这种情况下,computeIntersectionPoint(LatLng p1、double brng1、LatLng p2、double brng2)在这种情况下,您可以通过两条生成的线来查找交点-得到绿线和红线交叉点的板条,这会得到2板条1 n 2。-和两点1 n 2的呼吸,并使用该功能。是这样的。谢谢你的回复,我对这个轴承概念有点陌生。我仍然不明白在computeIntersectionPoint函数中必须传递什么。我可以告诉你我是如何实现这一点的。你能告诉我你的爱弥儿身份证吗?或者发邮件到拉纳。ranvijay@weboniselab.comyocanto在iOS上得体地使用JS,不管怎么说,这个问题显然是关于iOS的。
    public static double[] computeDestinationAndBearing(double lat1, double lon1,
                                                        double brng, double dist) {
        double results[] = new double[3];
        double a = 6378137, b = 6356752.3142, f = 1 / 298.257223563; // WGS-84
        // ellipsiod
        double s = dist;
        double alpha1 = toRad(brng);
        double sinAlpha1 = Math.sin(alpha1);
        double cosAlpha1 = Math.cos(alpha1);
    
        double tanU1 = (1 - f) * Math.tan(toRad(lat1));
        double cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1;
        double sigma1 = Math.atan2(tanU1, cosAlpha1);
        double sinAlpha = cosU1 * sinAlpha1;
        double cosSqAlpha = 1 - sinAlpha * sinAlpha;
        double uSq = cosSqAlpha * (a * a - b * b) / (b * b);
        double A = 1 + uSq / 16384
                * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
        double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
        double sinSigma = 0, cosSigma = 0, deltaSigma = 0, cos2SigmaM = 0;
        double sigma = s / (b * A), sigmaP = 2 * Math.PI;
    
        while (Math.abs(sigma - sigmaP) > 1e-12) {
            cos2SigmaM = Math.cos(2 * sigma1 + sigma);
            sinSigma = Math.sin(sigma);
            cosSigma = Math.cos(sigma);
            deltaSigma = B
                    * sinSigma
                    * (cos2SigmaM + B
                    / 4
                    * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6
                    * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma)
                    * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
            sigmaP = sigma;
            sigma = s / (b * A) + deltaSigma;
        }
    
        double tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
        double lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
                (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp));
        double lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1
                * sinSigma * cosAlpha1);
        double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
        double L = lambda
                - (1 - C)
                * f
                * sinAlpha
                * (sigma + C * sinSigma
                * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
        double lon2 = (toRad(lon1) + L + 3 * Math.PI) % (2 * Math.PI) - Math.PI; // normalise
        // to
        // -180...+180
    
        double revAz = Math.atan2(sinAlpha, -tmp); // final bearing, if required
    
        results[0] = toDegrees(lat2);
        results[1] = toDegrees(lon2);
        results[2] = toDegrees(revAz);
        return results;
    }
    
    private static double toRad(double angle) {
        return angle * Math.PI / 180;
    }
    
    private static double toDegrees(double radians) {
        return radians * 180 / Math.PI;
    }
    
        public static LatLng computeIntersectionPoint(LatLng p1, double brng1, LatLng p2, double brng2) {
        double lat1 = toRad(p1.latitude), lng1 = toRad(p1.longitude);
        double lat2 = toRad(p2.latitude), lng2 = toRad(p2.longitude);
        double brng13 = toRad(brng1), brng23 = toRad(brng2);
        double dlat = lat2 - lat1, dlng = lng2 - lng1;
        double delta12 = 2 * Math.asin(Math.sqrt(Math.sin(dlat / 2) * Math.sin(dlat / 2)
                + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dlng / 2) * Math.sin(dlng / 2)));
    
        if (delta12 == 0) return null;
    
    
        double initBrng1 = Math.acos((Math.sin(lat2) - Math.sin(lat1) * Math.cos(delta12)) / (Math.sin(delta12) * Math.cos(lat1)));
    
        double initBrng2 = Math.acos((Math.sin(lat1) - Math.sin(lat2) * Math.cos(delta12)) / (Math.sin(delta12) * Math.cos(lat2)));
    
        double brng12 = Math.sin(lng2 - lng1) > 0 ? initBrng1 : 2 * Math.PI - initBrng1;
        double brng21 = Math.sin(lng2 - lng1) > 0 ? 2 * Math.PI - initBrng2 : initBrng2;
    
    
        double alpha1 = (brng13 - brng12 + Math.PI) % (2 * Math.PI) - Math.PI; 
        double alpha2 = (brng21 - brng23 + Math.PI) % (2 * Math.PI) - Math.PI; 
    
        double alpha3 = Math.acos(-Math.cos(alpha1) * Math.cos(alpha2) + Math.sin(alpha1) * Math.sin(alpha2) * Math.cos(delta12));
        double delta13 = Math.atan2(Math.sin(delta12) * Math.sin(alpha1) * Math.sin(alpha2), Math.cos(alpha2) + Math.cos(alpha1) * Math.cos(alpha3));
        double lat3 = Math.asin(Math.sin(lat1) * Math.cos(delta13) + Math.cos(lat1) * Math.sin(delta13) * Math.cos(brng13));
        double dlng13 = Math.atan2(Math.sin(brng13) * Math.sin(delta13) * Math.cos(lat1), Math.cos(delta13) - Math.sin(lat1) * Math.sin(lat3));
        double lng3 = lng1 + dlng13;
    
        return new LatLng(toDegrees(lat3), (toDegrees(lng3) + 540) % 360 - 180); 
    }
    
    double distance = 0.0001;
    List bufferedPolygonList = AreaBuffer.buffer(pointList, distance);