{"version":3,"sources":["jsdelivr-header.js","/npm/geojson-qt-utils@1.1.0/geojson-utils.js"],"names":[],"mappings":"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","file":"/npm/geojson-qt-utils@1.1.0/geojson-utils.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/geojson-qt-utils@1.1.0/geojson-utils.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","(function () {\n  var gju = {};\n\n  // Export the geojson object for **CommonJS**\n  if (typeof module !== 'undefined' && module.exports) {\n    module.exports = gju;\n  }\n\n  // adapted from http://www.kevlindev.com/gui/math/intersection/Intersection.js\n  gju.lineStringsIntersect = function (l1, l2) {\n    var intersects = [];\n    for (var i = 0; i <= l1.coordinates.length - 2; ++i) {\n      for (var j = 0; j <= l2.coordinates.length - 2; ++j) {\n        var a1 = {\n          x: l1.coordinates[i][1],\n          y: l1.coordinates[i][0]\n        },\n          a2 = {\n            x: l1.coordinates[i + 1][1],\n            y: l1.coordinates[i + 1][0]\n          },\n          b1 = {\n            x: l2.coordinates[j][1],\n            y: l2.coordinates[j][0]\n          },\n          b2 = {\n            x: l2.coordinates[j + 1][1],\n            y: l2.coordinates[j + 1][0]\n          },\n          ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),\n          ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),\n          u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);\n        if (u_b != 0) {\n          var ua = ua_t / u_b,\n            ub = ub_t / u_b;\n          if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n            intersects.push({\n              'type': 'Point',\n              'coordinates': [a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)]\n            });\n          }\n        }\n      }\n    }\n    if (intersects.length == 0) intersects = false;\n    return intersects;\n  }\n\n  // Bounding Box\n\n  function boundingBoxAroundPolyCoords (coords) {\n    var xAll = [], yAll = []\n\n    for (var i = 0; i < coords[0].length; i++) {\n      xAll.push(coords[0][i][1])\n      yAll.push(coords[0][i][0])\n    }\n\n    xAll = xAll.sort(function (a,b) { return a - b })\n    yAll = yAll.sort(function (a,b) { return a - b })\n\n    return [ [xAll[0], yAll[0]], [xAll[xAll.length - 1], yAll[yAll.length - 1]] ]\n  }\n\n  gju.pointInBoundingBox = function (point, bounds) {\n    return !(point.coordinates[1] < bounds[0][0] || point.coordinates[1] > bounds[1][0] || point.coordinates[0] < bounds[0][1] || point.coordinates[0] > bounds[1][1]) \n  }\n\n  // Point in Polygon\n  // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html#Listing the Vertices\n\n  function pnpoly (x,y,coords) {\n    var vert = [ [0,0] ]\n\n    for (var i = 0; i < coords.length; i++) {\n      for (var j = 0; j < coords[i].length; j++) {\n        vert.push(coords[i][j])\n      }\n\t  vert.push(coords[i][0])\n      vert.push([0,0])\n    }\n\n    var inside = false\n    for (var i = 0, j = vert.length - 1; i < vert.length; j = i++) {\n      if (((vert[i][0] > y) != (vert[j][0] > y)) && (x < (vert[j][1] - vert[i][1]) * (y - vert[i][0]) / (vert[j][0] - vert[i][0]) + vert[i][1])) inside = !inside\n    }\n\n    return inside\n  }\n\n  gju.pointInPolygon = function (p, poly) {\n    var coords = (poly.type == \"Polygon\") ? [ poly.coordinates ] : poly.coordinates\n\n    var insideBox = false\n    for (var i = 0; i < coords.length; i++) {\n      if (gju.pointInBoundingBox(p, boundingBoxAroundPolyCoords(coords[i]))) insideBox = true\n    }\n    if (!insideBox) return false\n\n    var insidePoly = false\n    for (var i = 0; i < coords.length; i++) {\n      if (pnpoly(p.coordinates[1], p.coordinates[0], coords[i])) insidePoly = true\n    }\n\n    return insidePoly\n  }\n\n  // support multi (but not donut) polygons\n  gju.pointInMultiPolygon = function (p, poly) {\n    var coords_array = (poly.type == \"MultiPolygon\") ? [ poly.coordinates ] : poly.coordinates\n\n    var insideBox = false\n    var insidePoly = false\n    for (var i = 0; i < coords_array.length; i++){\n      var coords = coords_array[i];\n      for (var j = 0; j < coords.length; j++) {\n        if (!insideBox){\n          if (gju.pointInBoundingBox(p, boundingBoxAroundPolyCoords(coords[j]))) {\n            insideBox = true\n          }\n        }\n      }\n      if (!insideBox) return false\n      for (var j = 0; j < coords.length; j++) {\n        if (!insidePoly){\n          if (pnpoly(p.coordinates[1], p.coordinates[0], coords[j])) {\n            insidePoly = true\n          }\n        }\n      }\n    }\n\n    return insidePoly\n  }\n\n  gju.numberToRadius = function (number) {\n    return number * Math.PI / 180;\n  }\n\n  gju.numberToDegree = function (number) {\n    return number * 180 / Math.PI;\n  }\n\n  // written with help from @tautologe\n  gju.drawCircle = function (radiusInMeters, centerPoint, steps) {\n    var center = [centerPoint.coordinates[1], centerPoint.coordinates[0]],\n      dist = (radiusInMeters / 1000) / 6371,\n      // convert meters to radiant\n      radCenter = [gju.numberToRadius(center[0]), gju.numberToRadius(center[1])],\n      steps = steps || 15,\n      // 15 sided circle\n      poly = [[center[0], center[1]]];\n    for (var i = 0; i < steps; i++) {\n      var brng = 2 * Math.PI * i / steps;\n      var lat = Math.asin(Math.sin(radCenter[0]) * Math.cos(dist)\n              + Math.cos(radCenter[0]) * Math.sin(dist) * Math.cos(brng));\n      var lng = radCenter[1] + Math.atan2(Math.sin(brng) * Math.sin(dist) * Math.cos(radCenter[0]),\n                                          Math.cos(dist) - Math.sin(radCenter[0]) * Math.sin(lat));\n      poly[i] = [];\n      poly[i][1] = gju.numberToDegree(lat);\n      poly[i][0] = gju.numberToDegree(lng);\n    }\n    return {\n      \"type\": \"Polygon\",\n      \"coordinates\": [poly]\n    };\n  }\n\n  // assumes rectangle starts at lower left point\n  gju.rectangleCentroid = function (rectangle) {\n    var bbox = rectangle.coordinates[0];\n    var xmin = bbox[0][0],\n      ymin = bbox[0][1],\n      xmax = bbox[2][0],\n      ymax = bbox[2][1];\n    var xwidth = xmax - xmin;\n    var ywidth = ymax - ymin;\n    return {\n      'type': 'Point',\n      'coordinates': [xmin + xwidth / 2, ymin + ywidth / 2]\n    };\n  }\n\n  // from http://www.movable-type.co.uk/scripts/latlong.html\n  gju.pointDistance = function (pt1, pt2) {\n    var lon1 = pt1.coordinates[0],\n      lat1 = pt1.coordinates[1],\n      lon2 = pt2.coordinates[0],\n      lat2 = pt2.coordinates[1],\n      dLat = gju.numberToRadius(lat2 - lat1),\n      dLon = gju.numberToRadius(lon2 - lon1),\n      a = Math.pow(Math.sin(dLat / 2), 2) + Math.cos(gju.numberToRadius(lat1))\n        * Math.cos(gju.numberToRadius(lat2)) * Math.pow(Math.sin(dLon / 2), 2),\n      c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n    return (6371 * c) * 1000; // returns meters\n  },\n\n  // checks if geometry lies entirely within a circle\n  // works with Point, LineString, Polygon\n  gju.geometryWithinRadius = function (geometry, center, radius) {\n    if (geometry.type == 'Point') {\n      return gju.pointDistance(geometry, center) <= radius;\n    } else if (geometry.type == 'LineString' || geometry.type == 'Polygon') {\n      var point = {};\n      var coordinates;\n      if (geometry.type == 'Polygon') {\n        // it's enough to check the exterior ring of the Polygon\n        coordinates = geometry.coordinates[0];\n      } else {\n        coordinates = geometry.coordinates;\n      }\n      for (var i in coordinates) {\n        point.coordinates = coordinates[i];\n        if (gju.pointDistance(point, center) > radius) {\n          return false;\n        }\n      }\n    }\n    return true;\n  }\n\n  // adapted from http://paulbourke.net/geometry/polyarea/javascript.txt\n  gju.area = function (polygon) {\n    var area = 0;\n    // TODO: polygon holes at coordinates[1]\n    var points = polygon.coordinates[0];\n    var j = points.length - 1;\n    var p1, p2;\n\n    for (var i = 0; i < points.length; j = i++) {\n      var p1 = {\n        x: points[i][1],\n        y: points[i][0]\n      };\n      var p2 = {\n        x: points[j][1],\n        y: points[j][0]\n      };\n      area += p1.x * p2.y;\n      area -= p1.y * p2.x;\n    }\n\n    area /= 2;\n    return area;\n  },\n\n  // adapted from http://paulbourke.net/geometry/polyarea/javascript.txt\n  gju.centroid = function (polygon) {\n    var f, x = 0,\n      y = 0;\n    // TODO: polygon holes at coordinates[1]\n    var points = polygon.coordinates[0];\n    var j = points.length - 1;\n    var p1, p2;\n\n    for (var i = 0; i < points.length; j = i++) {\n      var p1 = {\n        x: points[i][1],\n        y: points[i][0]\n      };\n      var p2 = {\n        x: points[j][1],\n        y: points[j][0]\n      };\n      f = p1.x * p2.y - p2.x * p1.y;\n      x += (p1.x + p2.x) * f;\n      y += (p1.y + p2.y) * f;\n    }\n\n    f = gju.area(polygon) * 6;\n    return {\n      'type': 'Point',\n      'coordinates': [y / f, x / f]\n    };\n  },\n\n  gju.simplify = function (source, kink) { /* source[] array of geojson points */\n    /* kink\tin metres, kinks above this depth kept  */\n    /* kink depth is the height of the triangle abc where a-b and b-c are two consecutive line segments */\n    kink = kink || 20;\n    source = source.map(function (o) {\n      return {\n        lng: o.coordinates[0],\n        lat: o.coordinates[1]\n      }\n    });\n\n    var n_source, n_stack, n_dest, start, end, i, sig;\n    var dev_sqr, max_dev_sqr, band_sqr;\n    var x12, y12, d12, x13, y13, d13, x23, y23, d23;\n    var F = (Math.PI / 180.0) * 0.5;\n    var index = new Array(); /* aray of indexes of source points to include in the reduced line */\n    var sig_start = new Array(); /* indices of start & end of working section */\n    var sig_end = new Array();\n\n    /* check for simple cases */\n\n    if (source.length < 3) return (source); /* one or two points */\n\n    /* more complex case. initialize stack */\n\n    n_source = source.length;\n    band_sqr = kink * 360.0 / (2.0 * Math.PI * 6378137.0); /* Now in degrees */\n    band_sqr *= band_sqr;\n    n_dest = 0;\n    sig_start[0] = 0;\n    sig_end[0] = n_source - 1;\n    n_stack = 1;\n\n    /* while the stack is not empty  ... */\n    while (n_stack > 0) {\n\n      /* ... pop the top-most entries off the stacks */\n\n      start = sig_start[n_stack - 1];\n      end = sig_end[n_stack - 1];\n      n_stack--;\n\n      if ((end - start) > 1) { /* any intermediate points ? */\n\n        /* ... yes, so find most deviant intermediate point to\n        either side of line joining start & end points */\n\n        x12 = (source[end].lng() - source[start].lng());\n        y12 = (source[end].lat() - source[start].lat());\n        if (Math.abs(x12) > 180.0) x12 = 360.0 - Math.abs(x12);\n        x12 *= Math.cos(F * (source[end].lat() + source[start].lat())); /* use avg lat to reduce lng */\n        d12 = (x12 * x12) + (y12 * y12);\n\n        for (i = start + 1, sig = start, max_dev_sqr = -1.0; i < end; i++) {\n\n          x13 = source[i].lng() - source[start].lng();\n          y13 = source[i].lat() - source[start].lat();\n          if (Math.abs(x13) > 180.0) x13 = 360.0 - Math.abs(x13);\n          x13 *= Math.cos(F * (source[i].lat() + source[start].lat()));\n          d13 = (x13 * x13) + (y13 * y13);\n\n          x23 = source[i].lng() - source[end].lng();\n          y23 = source[i].lat() - source[end].lat();\n          if (Math.abs(x23) > 180.0) x23 = 360.0 - Math.abs(x23);\n          x23 *= Math.cos(F * (source[i].lat() + source[end].lat()));\n          d23 = (x23 * x23) + (y23 * y23);\n\n          if (d13 >= (d12 + d23)) dev_sqr = d23;\n          else if (d23 >= (d12 + d13)) dev_sqr = d13;\n          else dev_sqr = (x13 * y12 - y13 * x12) * (x13 * y12 - y13 * x12) / d12; // solve triangle\n          if (dev_sqr > max_dev_sqr) {\n            sig = i;\n            max_dev_sqr = dev_sqr;\n          }\n        }\n\n        if (max_dev_sqr < band_sqr) { /* is there a sig. intermediate point ? */\n          /* ... no, so transfer current start point */\n          index[n_dest] = start;\n          n_dest++;\n        } else { /* ... yes, so push two sub-sections on stack for further processing */\n          n_stack++;\n          sig_start[n_stack - 1] = sig;\n          sig_end[n_stack - 1] = end;\n          n_stack++;\n          sig_start[n_stack - 1] = start;\n          sig_end[n_stack - 1] = sig;\n        }\n      } else { /* ... no intermediate points, so transfer current start point */\n        index[n_dest] = start;\n        n_dest++;\n      }\n    }\n\n    /* transfer last point */\n    index[n_dest] = n_source - 1;\n    n_dest++;\n\n    /* make return array */\n    var r = new Array();\n    for (var i = 0; i < n_dest; i++)\n      r.push(source[index[i]]);\n\n    return r.map(function (o) {\n      return {\n        type: \"Point\",\n        coordinates: [o.lng, o.lat]\n      }\n    });\n  }\n\n  // http://www.movable-type.co.uk/scripts/latlong.html#destPoint\n  gju.destinationPoint = function (pt, brng, dist) {\n    dist = dist/6371;  // convert dist to angular distance in radians\n    brng = gju.numberToRadius(brng);\n\n    var lon1 = gju.numberToRadius(pt.coordinates[0]);\n    var lat1 = gju.numberToRadius(pt.coordinates[1]);\n\n    var lat2 = Math.asin( Math.sin(lat1)*Math.cos(dist) +\n                          Math.cos(lat1)*Math.sin(dist)*Math.cos(brng) );\n    var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(dist)*Math.cos(lat1),\n                                 Math.cos(dist)-Math.sin(lat1)*Math.sin(lat2));\n    lon2 = (lon2+3*Math.PI) % (2*Math.PI) - Math.PI;  // normalise to -180..+180º\n\n    return {\n      'type': 'Point',\n      'coordinates': [gju.numberToDegree(lon2), gju.numberToDegree(lat2)]\n    };\n  };\n\n})();\n"]}