node-red-contrib-tak-registration 0.11.5 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node_modules/@types/node/README.md +2 -2
- package/node_modules/@types/node/assert.d.ts +88 -44
- package/node_modules/@types/node/async_hooks.d.ts +17 -15
- package/node_modules/@types/node/buffer.d.ts +37 -36
- package/node_modules/@types/node/child_process.d.ts +38 -34
- package/node_modules/@types/node/cluster.d.ts +165 -19
- package/node_modules/@types/node/console.d.ts +64 -27
- package/node_modules/@types/node/crypto.d.ts +139 -72
- package/node_modules/@types/node/dgram.d.ts +24 -14
- package/node_modules/@types/node/diagnostics_channel.d.ts +365 -2
- package/node_modules/@types/node/dns/promises.d.ts +79 -28
- package/node_modules/@types/node/dns.d.ts +124 -69
- package/node_modules/@types/node/dom-events.d.ts +2 -0
- package/node_modules/@types/node/domain.d.ts +4 -4
- package/node_modules/@types/node/events.d.ts +115 -63
- package/node_modules/@types/node/fs/promises.d.ts +18 -12
- package/node_modules/@types/node/fs.d.ts +72 -46
- package/node_modules/@types/node/globals.d.ts +27 -0
- package/node_modules/@types/node/http.d.ts +75 -55
- package/node_modules/@types/node/http2.d.ts +83 -47
- package/node_modules/@types/node/https.d.ts +3 -3
- package/node_modules/@types/node/index.d.ts +1 -0
- package/node_modules/@types/node/inspector.d.ts +5 -6
- package/node_modules/@types/node/module.d.ts +14 -0
- package/node_modules/@types/node/net.d.ts +66 -16
- package/node_modules/@types/node/os.d.ts +29 -12
- package/node_modules/@types/node/package.json +3 -16
- package/node_modules/@types/node/path.d.ts +1 -1
- package/node_modules/@types/node/perf_hooks.d.ts +320 -54
- package/node_modules/@types/node/process.d.ts +265 -50
- package/node_modules/@types/node/punycode.d.ts +4 -4
- package/node_modules/@types/node/querystring.d.ts +21 -9
- package/node_modules/@types/node/readline/promises.d.ts +9 -9
- package/node_modules/@types/node/readline.d.ts +21 -20
- package/node_modules/@types/node/repl.d.ts +10 -10
- package/node_modules/@types/node/sea.d.ts +153 -0
- package/node_modules/@types/node/stream/web.d.ts +18 -1
- package/node_modules/@types/node/stream.d.ts +62 -56
- package/node_modules/@types/node/string_decoder.d.ts +5 -5
- package/node_modules/@types/node/test.d.ts +445 -109
- package/node_modules/@types/node/timers/promises.d.ts +10 -6
- package/node_modules/@types/node/timers.d.ts +5 -5
- package/node_modules/@types/node/tls.d.ts +40 -33
- package/node_modules/@types/node/trace_events.d.ts +40 -25
- package/node_modules/@types/node/tty.d.ts +8 -8
- package/node_modules/@types/node/url.d.ts +73 -48
- package/node_modules/@types/node/util.d.ts +131 -22
- package/node_modules/@types/node/v8.d.ts +183 -10
- package/node_modules/@types/node/vm.d.ts +43 -22
- package/node_modules/@types/node/wasi.d.ts +38 -15
- package/node_modules/@types/node/worker_threads.d.ts +19 -16
- package/node_modules/@types/node/zlib.d.ts +16 -3
- package/node_modules/adm-zip/README.md +2 -1
- package/node_modules/adm-zip/adm-zip.js +46 -45
- package/node_modules/adm-zip/headers/entryHeader.js +14 -12
- package/node_modules/adm-zip/headers/mainHeader.js +1 -1
- package/node_modules/adm-zip/methods/inflater.js +6 -3
- package/node_modules/adm-zip/methods/zipcrypto.js +6 -2
- package/node_modules/adm-zip/package.json +2 -2
- package/node_modules/adm-zip/util/errors.js +1 -0
- package/node_modules/adm-zip/zipEntry.js +64 -43
- package/node_modules/adm-zip/zipFile.js +35 -35
- package/node_modules/axios/CHANGELOG.md +873 -711
- package/node_modules/axios/README.md +98 -8
- package/node_modules/axios/dist/axios.js +1461 -350
- package/node_modules/axios/dist/axios.js.map +1 -1
- package/node_modules/axios/dist/axios.min.js +1 -1
- package/node_modules/axios/dist/axios.min.js.map +1 -1
- package/node_modules/axios/dist/browser/axios.cjs +710 -306
- package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
- package/node_modules/axios/dist/esm/axios.js +710 -306
- package/node_modules/axios/dist/esm/axios.js.map +1 -1
- package/node_modules/axios/dist/esm/axios.min.js +1 -1
- package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
- package/node_modules/axios/dist/node/axios.cjs +628 -250
- package/node_modules/axios/dist/node/axios.cjs.map +1 -1
- package/node_modules/axios/index.d.cts +6 -3
- package/node_modules/axios/index.d.ts +6 -3
- package/node_modules/axios/lib/adapters/adapters.js +3 -1
- package/node_modules/axios/lib/adapters/fetch.js +227 -0
- package/node_modules/axios/lib/adapters/http.js +7 -3
- package/node_modules/axios/lib/adapters/xhr.js +31 -101
- package/node_modules/axios/lib/core/Axios.js +28 -1
- package/node_modules/axios/lib/core/AxiosHeaders.js +4 -0
- package/node_modules/axios/lib/core/mergeConfig.js +1 -1
- package/node_modules/axios/lib/defaults/index.js +7 -5
- package/node_modules/axios/lib/env/data.js +1 -1
- package/node_modules/axios/lib/helpers/AxiosTransformStream.js +9 -8
- package/node_modules/axios/lib/helpers/combineURLs.js +1 -1
- package/node_modules/axios/lib/helpers/composeSignals.js +46 -0
- package/node_modules/axios/lib/helpers/formDataToJSON.js +3 -0
- package/node_modules/axios/lib/helpers/progressEventReducer.js +32 -0
- package/node_modules/axios/lib/helpers/resolveConfig.js +57 -0
- package/node_modules/axios/lib/helpers/throttle.js +5 -3
- package/node_modules/axios/lib/helpers/trackStream.js +55 -0
- package/node_modules/axios/lib/platform/common/utils.js +4 -1
- package/node_modules/axios/lib/utils.js +7 -2
- package/node_modules/axios/package.json +27 -26
- package/node_modules/call-bind/CHANGELOG.md +16 -0
- package/node_modules/call-bind/index.js +2 -11
- package/node_modules/call-bind/package.json +11 -6
- package/node_modules/define-data-property/CHANGELOG.md +29 -0
- package/node_modules/define-data-property/index.d.ts +12 -3
- package/node_modules/define-data-property/index.js +4 -16
- package/node_modules/define-data-property/package.json +26 -33
- package/node_modules/define-data-property/test/index.js +10 -10
- package/node_modules/es-define-property/.eslintrc +13 -0
- package/node_modules/es-define-property/.github/FUNDING.yml +12 -0
- package/node_modules/es-define-property/.nycrc +9 -0
- package/node_modules/es-define-property/CHANGELOG.md +15 -0
- package/node_modules/es-define-property/LICENSE +21 -0
- package/node_modules/es-define-property/README.md +49 -0
- package/node_modules/es-define-property/index.d.ts +3 -0
- package/node_modules/es-define-property/index.js +16 -0
- package/node_modules/es-define-property/package.json +81 -0
- package/node_modules/es-define-property/test/index.js +55 -0
- package/node_modules/es-define-property/tsconfig.json +50 -0
- package/node_modules/es-errors/.eslintrc +5 -0
- package/node_modules/es-errors/.github/FUNDING.yml +12 -0
- package/node_modules/es-errors/CHANGELOG.md +40 -0
- package/node_modules/es-errors/LICENSE +21 -0
- package/node_modules/es-errors/README.md +55 -0
- package/node_modules/es-errors/eval.d.ts +3 -0
- package/node_modules/es-errors/eval.js +4 -0
- package/node_modules/es-errors/index.d.ts +3 -0
- package/node_modules/es-errors/index.js +4 -0
- package/node_modules/es-errors/package.json +80 -0
- package/node_modules/es-errors/range.d.ts +3 -0
- package/node_modules/es-errors/range.js +4 -0
- package/node_modules/es-errors/ref.d.ts +3 -0
- package/node_modules/es-errors/ref.js +4 -0
- package/node_modules/es-errors/syntax.d.ts +3 -0
- package/node_modules/es-errors/syntax.js +4 -0
- package/node_modules/es-errors/test/index.js +19 -0
- package/node_modules/es-errors/tsconfig.json +49 -0
- package/node_modules/es-errors/type.d.ts +3 -0
- package/node_modules/es-errors/type.js +4 -0
- package/node_modules/es-errors/uri.d.ts +3 -0
- package/node_modules/es-errors/uri.js +4 -0
- package/node_modules/fast-xml-parser/CHANGELOG.md +17 -0
- package/node_modules/fast-xml-parser/README.md +9 -15
- package/node_modules/fast-xml-parser/package.json +4 -1
- package/node_modules/fast-xml-parser/src/fxp.d.ts +365 -71
- package/node_modules/fast-xml-parser/src/v5/CharsSymbol.js +16 -0
- package/node_modules/fast-xml-parser/src/v5/EntitiesParser.js +107 -0
- package/node_modules/fast-xml-parser/src/v5/OptionsBuilder.js +64 -0
- package/node_modules/fast-xml-parser/src/v5/OutputBuilders/BaseOutputBuilder.js +71 -0
- package/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsArrBuilder.js +103 -0
- package/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsMinArrBuilder.js +102 -0
- package/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsObjBuilder.js +156 -0
- package/node_modules/fast-xml-parser/src/v5/OutputBuilders/ParserOptionsBuilder.js +96 -0
- package/node_modules/fast-xml-parser/src/v5/Report.js +0 -0
- package/node_modules/fast-xml-parser/src/v5/TagPath.js +81 -0
- package/node_modules/fast-xml-parser/src/v5/TagPathMatcher.js +15 -0
- package/node_modules/fast-xml-parser/src/v5/XMLParser.js +85 -0
- package/node_modules/fast-xml-parser/src/v5/Xml2JsParser.js +237 -0
- package/node_modules/fast-xml-parser/src/v5/XmlPartReader.js +212 -0
- package/node_modules/fast-xml-parser/src/v5/XmlSpecialTagsReader.js +118 -0
- package/node_modules/fast-xml-parser/src/v5/inputSource/BufferSource.js +118 -0
- package/node_modules/fast-xml-parser/src/v5/inputSource/StringSource.js +123 -0
- package/node_modules/fast-xml-parser/src/v5/valueParsers/EntitiesParser.js +107 -0
- package/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParser.js +23 -0
- package/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParserExt.js +20 -0
- package/node_modules/fast-xml-parser/src/v5/valueParsers/currency.js +31 -0
- package/node_modules/fast-xml-parser/src/v5/valueParsers/join.js +14 -0
- package/node_modules/fast-xml-parser/src/v5/valueParsers/number.js +16 -0
- package/node_modules/fast-xml-parser/src/v5/valueParsers/trim.js +8 -0
- package/node_modules/fast-xml-parser/src/validator.js +2 -0
- package/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js +18 -9
- package/node_modules/follow-redirects/index.js +115 -76
- package/node_modules/follow-redirects/package.json +1 -1
- package/node_modules/get-intrinsic/CHANGELOG.md +18 -0
- package/node_modules/get-intrinsic/index.js +15 -7
- package/node_modules/get-intrinsic/package.json +12 -12
- package/node_modules/has-property-descriptors/CHANGELOG.md +8 -0
- package/node_modules/has-property-descriptors/index.js +3 -14
- package/node_modules/has-property-descriptors/package.json +5 -5
- package/node_modules/has-proto/CHANGELOG.md +15 -0
- package/node_modules/has-proto/index.d.ts +3 -0
- package/node_modules/has-proto/index.js +5 -1
- package/node_modules/has-proto/package.json +9 -5
- package/node_modules/has-proto/tsconfig.json +49 -0
- package/node_modules/has-tostringtag/.eslintrc +0 -6
- package/node_modules/has-tostringtag/.nycrc +13 -0
- package/node_modules/has-tostringtag/CHANGELOG.md +22 -0
- package/node_modules/has-tostringtag/index.d.ts +3 -0
- package/node_modules/has-tostringtag/index.js +1 -0
- package/node_modules/has-tostringtag/package.json +37 -13
- package/node_modules/has-tostringtag/shams.d.ts +3 -0
- package/node_modules/has-tostringtag/shams.js +1 -0
- package/node_modules/has-tostringtag/test/shams/core-js.js +3 -0
- package/node_modules/has-tostringtag/test/shams/get-own-property-symbols.js +2 -0
- package/node_modules/has-tostringtag/test/tests.js +2 -1
- package/node_modules/has-tostringtag/tsconfig.json +49 -0
- package/node_modules/hasown/CHANGELOG.md +20 -0
- package/node_modules/hasown/index.d.ts +3 -3
- package/node_modules/hasown/index.js +1 -1
- package/node_modules/hasown/package.json +16 -15
- package/node_modules/hasown/tsconfig.json +3 -46
- package/node_modules/object-is/.eslintrc +1 -1
- package/node_modules/object-is/.nycrc +0 -4
- package/node_modules/object-is/CHANGELOG.md +25 -0
- package/node_modules/object-is/README.md +20 -20
- package/node_modules/object-is/package.json +23 -14
- package/node_modules/polygon-clipping/README.md +29 -26
- package/node_modules/polygon-clipping/dist/polygon-clipping.cjs.js +1398 -1421
- package/node_modules/polygon-clipping/dist/polygon-clipping.d.ts +13 -10
- package/node_modules/polygon-clipping/dist/polygon-clipping.esm.js +1139 -1427
- package/node_modules/polygon-clipping/dist/polygon-clipping.umd.js +1770 -1831
- package/node_modules/polygon-clipping/dist/polygon-clipping.umd.min.js +22 -8
- package/node_modules/polygon-clipping/dist/polygon-clipping.umd.min.js.map +1 -1
- package/node_modules/polygon-clipping/node_modules/robust-predicates/LICENSE +24 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/README.md +82 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/esm/incircle.js +765 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/esm/insphere.js +766 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/esm/orient2d.js +184 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/esm/orient3d.js +462 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/esm/util.js +138 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/index.d.ts +49 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/index.js +5 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/package.json +75 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/incircle.js +908 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/incircle.min.js +1 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/insphere.js +914 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/insphere.min.js +1 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/orient2d.js +280 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/orient2d.min.js +1 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/orient3d.js +601 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/orient3d.min.js +1 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/predicates.js +2328 -0
- package/node_modules/polygon-clipping/node_modules/robust-predicates/umd/predicates.min.js +1 -0
- package/node_modules/polygon-clipping/package.json +30 -25
- package/node_modules/protobufjs/LICENSE +39 -39
- package/node_modules/protobufjs/README.md +727 -740
- package/node_modules/protobufjs/dist/light/protobuf.js +6264 -6264
- package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.js +1928 -1928
- package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +2 -2
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.js +7978 -7961
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/ext/debug/README.md +4 -4
- package/node_modules/protobufjs/ext/debug/index.js +71 -71
- package/node_modules/protobufjs/ext/descriptor/README.md +72 -72
- package/node_modules/protobufjs/ext/descriptor/index.d.ts +191 -191
- package/node_modules/protobufjs/ext/descriptor/index.js +1052 -1052
- package/node_modules/protobufjs/ext/descriptor/test.js +54 -54
- package/node_modules/protobufjs/google/LICENSE +27 -27
- package/node_modules/protobufjs/google/README.md +1 -1
- package/node_modules/protobufjs/google/api/annotations.json +82 -82
- package/node_modules/protobufjs/google/api/annotations.proto +10 -10
- package/node_modules/protobufjs/google/api/http.json +85 -85
- package/node_modules/protobufjs/google/api/http.proto +30 -30
- package/node_modules/protobufjs/google/protobuf/api.json +117 -117
- package/node_modules/protobufjs/google/protobuf/api.proto +33 -33
- package/node_modules/protobufjs/google/protobuf/descriptor.json +738 -738
- package/node_modules/protobufjs/google/protobuf/descriptor.proto +286 -286
- package/node_modules/protobufjs/google/protobuf/source_context.json +19 -19
- package/node_modules/protobufjs/google/protobuf/source_context.proto +7 -7
- package/node_modules/protobufjs/google/protobuf/type.json +201 -201
- package/node_modules/protobufjs/google/protobuf/type.proto +89 -89
- package/node_modules/protobufjs/index.d.ts +2741 -2741
- package/node_modules/protobufjs/index.js +4 -4
- package/node_modules/protobufjs/light.d.ts +2 -2
- package/node_modules/protobufjs/light.js +3 -3
- package/node_modules/protobufjs/minimal.d.ts +2 -2
- package/node_modules/protobufjs/minimal.js +4 -4
- package/node_modules/protobufjs/package.json +111 -111
- package/node_modules/protobufjs/scripts/postinstall.js +32 -32
- package/node_modules/protobufjs/src/common.js +399 -399
- package/node_modules/protobufjs/src/converter.js +301 -301
- package/node_modules/protobufjs/src/decoder.js +129 -129
- package/node_modules/protobufjs/src/encoder.js +100 -100
- package/node_modules/protobufjs/src/enum.js +198 -198
- package/node_modules/protobufjs/src/field.js +377 -377
- package/node_modules/protobufjs/src/index-light.js +104 -104
- package/node_modules/protobufjs/src/index-minimal.js +36 -36
- package/node_modules/protobufjs/src/index.js +12 -12
- package/node_modules/protobufjs/src/mapfield.js +126 -126
- package/node_modules/protobufjs/src/message.js +138 -138
- package/node_modules/protobufjs/src/method.js +160 -160
- package/node_modules/protobufjs/src/namespace.js +433 -433
- package/node_modules/protobufjs/src/object.js +243 -243
- package/node_modules/protobufjs/src/oneof.js +203 -203
- package/node_modules/protobufjs/src/parse.js +889 -872
- package/node_modules/protobufjs/src/reader.js +416 -416
- package/node_modules/protobufjs/src/reader_buffer.js +51 -51
- package/node_modules/protobufjs/src/root.js +368 -368
- package/node_modules/protobufjs/src/roots.js +18 -18
- package/node_modules/protobufjs/src/rpc/service.js +142 -142
- package/node_modules/protobufjs/src/rpc.js +36 -36
- package/node_modules/protobufjs/src/service.js +167 -167
- package/node_modules/protobufjs/src/tokenize.js +416 -416
- package/node_modules/protobufjs/src/type.js +589 -589
- package/node_modules/protobufjs/src/types.js +196 -196
- package/node_modules/protobufjs/src/typescript.jsdoc +15 -15
- package/node_modules/protobufjs/src/util/longbits.js +200 -200
- package/node_modules/protobufjs/src/util/minimal.js +438 -438
- package/node_modules/protobufjs/src/util.js +212 -212
- package/node_modules/protobufjs/src/verifier.js +176 -176
- package/node_modules/protobufjs/src/wrappers.js +102 -102
- package/node_modules/protobufjs/src/writer.js +465 -465
- package/node_modules/protobufjs/src/writer_buffer.js +85 -85
- package/node_modules/protobufjs/tsconfig.json +7 -7
- package/node_modules/regexp.prototype.flags/CHANGELOG.md +13 -0
- package/node_modules/regexp.prototype.flags/implementation.js +2 -2
- package/node_modules/regexp.prototype.flags/package.json +11 -10
- package/node_modules/regexp.prototype.flags/test/tests.js +13 -13
- package/node_modules/set-function-length/CHANGELOG.md +29 -0
- package/node_modules/set-function-length/env.d.ts +9 -0
- package/node_modules/set-function-length/env.js +10 -4
- package/node_modules/set-function-length/index.d.ts +7 -0
- package/node_modules/set-function-length/index.js +4 -3
- package/node_modules/set-function-length/package.json +29 -11
- package/node_modules/set-function-length/tsconfig.json +9 -0
- package/node_modules/set-function-name/.eslintrc +1 -0
- package/node_modules/set-function-name/CHANGELOG.md +9 -0
- package/node_modules/set-function-name/index.d.ts +5 -0
- package/node_modules/set-function-name/index.js +4 -3
- package/node_modules/set-function-name/package.json +28 -9
- package/node_modules/set-function-name/tsconfig.json +59 -0
- package/node_modules/uuid/CHANGELOG.md +18 -0
- package/node_modules/uuid/README.md +134 -16
- package/node_modules/uuid/dist/commonjs-browser/index.js +40 -15
- package/node_modules/uuid/dist/commonjs-browser/max.js +7 -0
- package/node_modules/uuid/dist/commonjs-browser/md5.js +30 -53
- package/node_modules/uuid/dist/commonjs-browser/native.js +3 -4
- package/node_modules/uuid/dist/commonjs-browser/nil.js +1 -2
- package/node_modules/uuid/dist/commonjs-browser/parse.js +14 -15
- package/node_modules/uuid/dist/commonjs-browser/regex.js +1 -2
- package/node_modules/uuid/dist/commonjs-browser/rng.js +2 -4
- package/node_modules/uuid/dist/commonjs-browser/sha1.js +27 -49
- package/node_modules/uuid/dist/commonjs-browser/stringify.js +10 -16
- package/node_modules/uuid/dist/commonjs-browser/v1.js +73 -49
- package/node_modules/uuid/dist/commonjs-browser/v1ToV6.js +26 -0
- package/node_modules/uuid/dist/commonjs-browser/v3.js +3 -8
- package/node_modules/uuid/dist/commonjs-browser/v35.js +15 -32
- package/node_modules/uuid/dist/commonjs-browser/v4.js +7 -18
- package/node_modules/uuid/dist/commonjs-browser/v5.js +3 -8
- package/node_modules/uuid/dist/commonjs-browser/v6.js +42 -0
- package/node_modules/uuid/dist/commonjs-browser/v6ToV1.js +26 -0
- package/node_modules/uuid/dist/commonjs-browser/v7.js +152 -0
- package/node_modules/uuid/dist/commonjs-browser/validate.js +2 -7
- package/node_modules/uuid/dist/commonjs-browser/version.js +2 -8
- package/node_modules/uuid/dist/esm-browser/index.js +9 -4
- package/node_modules/uuid/dist/esm-browser/max.js +1 -0
- package/node_modules/uuid/dist/esm-browser/md5.js +29 -50
- package/node_modules/uuid/dist/esm-browser/native.js +1 -1
- package/node_modules/uuid/dist/esm-browser/parse.js +12 -10
- package/node_modules/uuid/dist/esm-browser/regex.js +1 -1
- package/node_modules/uuid/dist/esm-browser/rng.js +3 -4
- package/node_modules/uuid/dist/esm-browser/sha1.js +26 -46
- package/node_modules/uuid/dist/esm-browser/stringify.js +9 -11
- package/node_modules/uuid/dist/esm-browser/v1.js +74 -44
- package/node_modules/uuid/dist/esm-browser/v1ToV6.js +20 -0
- package/node_modules/uuid/dist/esm-browser/v3.js +1 -1
- package/node_modules/uuid/dist/esm-browser/v35.js +14 -25
- package/node_modules/uuid/dist/esm-browser/v4.js +5 -9
- package/node_modules/uuid/dist/esm-browser/v5.js +1 -1
- package/node_modules/uuid/dist/esm-browser/v6.js +36 -0
- package/node_modules/uuid/dist/esm-browser/v6ToV1.js +20 -0
- package/node_modules/uuid/dist/esm-browser/v7.js +146 -0
- package/node_modules/uuid/dist/esm-browser/validate.js +0 -2
- package/node_modules/uuid/dist/esm-browser/version.js +0 -3
- package/node_modules/uuid/dist/esm-node/index.js +9 -4
- package/node_modules/uuid/dist/esm-node/max.js +1 -0
- package/node_modules/uuid/dist/esm-node/md5.js +1 -4
- package/node_modules/uuid/dist/esm-node/native.js +1 -1
- package/node_modules/uuid/dist/esm-node/parse.js +11 -9
- package/node_modules/uuid/dist/esm-node/regex.js +1 -1
- package/node_modules/uuid/dist/esm-node/rng.js +1 -3
- package/node_modules/uuid/dist/esm-node/sha1.js +1 -4
- package/node_modules/uuid/dist/esm-node/stringify.js +7 -9
- package/node_modules/uuid/dist/esm-node/v1.js +66 -36
- package/node_modules/uuid/dist/esm-node/v1ToV6.js +20 -0
- package/node_modules/uuid/dist/esm-node/v35.js +8 -19
- package/node_modules/uuid/dist/esm-node/v4.js +4 -8
- package/node_modules/uuid/dist/esm-node/v6.js +32 -0
- package/node_modules/uuid/dist/esm-node/v6ToV1.js +20 -0
- package/node_modules/uuid/dist/esm-node/v7.js +146 -0
- package/node_modules/uuid/dist/esm-node/validate.js +0 -2
- package/node_modules/uuid/dist/esm-node/version.js +0 -3
- package/node_modules/uuid/dist/index.js +40 -15
- package/node_modules/uuid/dist/max.js +7 -0
- package/node_modules/uuid/dist/md5-browser.js +8 -31
- package/node_modules/uuid/dist/md5.js +4 -10
- package/node_modules/uuid/dist/native-browser.js +2 -3
- package/node_modules/uuid/dist/native.js +5 -9
- package/node_modules/uuid/dist/nil.js +1 -2
- package/node_modules/uuid/dist/parse.js +13 -14
- package/node_modules/uuid/dist/regex.js +1 -2
- package/node_modules/uuid/dist/rng-browser.js +1 -3
- package/node_modules/uuid/dist/rng.js +3 -10
- package/node_modules/uuid/dist/sha1-browser.js +1 -23
- package/node_modules/uuid/dist/sha1.js +4 -10
- package/node_modules/uuid/dist/stringify.js +8 -14
- package/node_modules/uuid/dist/uuid-bin.js +12 -22
- package/node_modules/uuid/dist/v1.js +66 -42
- package/node_modules/uuid/dist/v1ToV6.js +26 -0
- package/node_modules/uuid/dist/v3.js +2 -7
- package/node_modules/uuid/dist/v35.js +11 -28
- package/node_modules/uuid/dist/v4.js +6 -17
- package/node_modules/uuid/dist/v5.js +2 -7
- package/node_modules/uuid/dist/v6.js +38 -0
- package/node_modules/uuid/dist/v6ToV1.js +26 -0
- package/node_modules/uuid/dist/v7.js +152 -0
- package/node_modules/uuid/dist/validate.js +2 -7
- package/node_modules/uuid/dist/version.js +2 -8
- package/node_modules/uuid/package.json +41 -34
- package/node_modules/uuid/wrapper.mjs +5 -0
- package/package.json +6 -6
- package/tak-ingest.js +5 -1
- package/tak-registration.js +8 -1
- package/node_modules/@types/node/ts4.8/assert/strict.d.ts +0 -8
- package/node_modules/@types/node/ts4.8/assert.d.ts +0 -996
- package/node_modules/@types/node/ts4.8/async_hooks.d.ts +0 -539
- package/node_modules/@types/node/ts4.8/buffer.d.ts +0 -2362
- package/node_modules/@types/node/ts4.8/child_process.d.ts +0 -1540
- package/node_modules/@types/node/ts4.8/cluster.d.ts +0 -432
- package/node_modules/@types/node/ts4.8/console.d.ts +0 -415
- package/node_modules/@types/node/ts4.8/constants.d.ts +0 -19
- package/node_modules/@types/node/ts4.8/crypto.d.ts +0 -4455
- package/node_modules/@types/node/ts4.8/dgram.d.ts +0 -586
- package/node_modules/@types/node/ts4.8/diagnostics_channel.d.ts +0 -191
- package/node_modules/@types/node/ts4.8/dns/promises.d.ts +0 -425
- package/node_modules/@types/node/ts4.8/dns.d.ts +0 -809
- package/node_modules/@types/node/ts4.8/dom-events.d.ts +0 -122
- package/node_modules/@types/node/ts4.8/domain.d.ts +0 -170
- package/node_modules/@types/node/ts4.8/events.d.ts +0 -879
- package/node_modules/@types/node/ts4.8/fs/promises.d.ts +0 -1239
- package/node_modules/@types/node/ts4.8/fs.d.ts +0 -4291
- package/node_modules/@types/node/ts4.8/globals.d.ts +0 -385
- package/node_modules/@types/node/ts4.8/globals.global.d.ts +0 -1
- package/node_modules/@types/node/ts4.8/http.d.ts +0 -1888
- package/node_modules/@types/node/ts4.8/http2.d.ts +0 -2382
- package/node_modules/@types/node/ts4.8/https.d.ts +0 -550
- package/node_modules/@types/node/ts4.8/index.d.ts +0 -88
- package/node_modules/@types/node/ts4.8/inspector.d.ts +0 -2747
- package/node_modules/@types/node/ts4.8/module.d.ts +0 -301
- package/node_modules/@types/node/ts4.8/net.d.ts +0 -949
- package/node_modules/@types/node/ts4.8/os.d.ts +0 -478
- package/node_modules/@types/node/ts4.8/path.d.ts +0 -191
- package/node_modules/@types/node/ts4.8/perf_hooks.d.ts +0 -639
- package/node_modules/@types/node/ts4.8/process.d.ts +0 -1539
- package/node_modules/@types/node/ts4.8/punycode.d.ts +0 -117
- package/node_modules/@types/node/ts4.8/querystring.d.ts +0 -141
- package/node_modules/@types/node/ts4.8/readline/promises.d.ts +0 -150
- package/node_modules/@types/node/ts4.8/readline.d.ts +0 -539
- package/node_modules/@types/node/ts4.8/repl.d.ts +0 -430
- package/node_modules/@types/node/ts4.8/stream/consumers.d.ts +0 -12
- package/node_modules/@types/node/ts4.8/stream/promises.d.ts +0 -83
- package/node_modules/@types/node/ts4.8/stream/web.d.ts +0 -350
- package/node_modules/@types/node/ts4.8/stream.d.ts +0 -1701
- package/node_modules/@types/node/ts4.8/string_decoder.d.ts +0 -67
- package/node_modules/@types/node/ts4.8/test.d.ts +0 -1382
- package/node_modules/@types/node/ts4.8/timers/promises.d.ts +0 -93
- package/node_modules/@types/node/ts4.8/timers.d.ts +0 -240
- package/node_modules/@types/node/ts4.8/tls.d.ts +0 -1210
- package/node_modules/@types/node/ts4.8/trace_events.d.ts +0 -182
- package/node_modules/@types/node/ts4.8/tty.d.ts +0 -208
- package/node_modules/@types/node/ts4.8/url.d.ts +0 -927
- package/node_modules/@types/node/ts4.8/util.d.ts +0 -2183
- package/node_modules/@types/node/ts4.8/v8.d.ts +0 -635
- package/node_modules/@types/node/ts4.8/vm.d.ts +0 -903
- package/node_modules/@types/node/ts4.8/wasi.d.ts +0 -158
- package/node_modules/@types/node/ts4.8/worker_threads.d.ts +0 -691
- package/node_modules/@types/node/ts4.8/zlib.d.ts +0 -517
- package/node_modules/define-data-property/index.d.ts.map +0 -1
- package/node_modules/hasown/index.d.ts.map +0 -1
- package/node_modules/object-is/.eslintignore +0 -1
- package/node_modules/polygon-clipping/CHANGELOG.md +0 -129
|
@@ -6,51 +6,33 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
6
6
|
|
|
7
7
|
var SplayTree__default = /*#__PURE__*/_interopDefaultLegacy(SplayTree);
|
|
8
8
|
|
|
9
|
-
function _classCallCheck(instance, Constructor) {
|
|
10
|
-
if (!(instance instanceof Constructor)) {
|
|
11
|
-
throw new TypeError("Cannot call a class as a function");
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function _defineProperties(target, props) {
|
|
16
|
-
for (var i = 0; i < props.length; i++) {
|
|
17
|
-
var descriptor = props[i];
|
|
18
|
-
descriptor.enumerable = descriptor.enumerable || false;
|
|
19
|
-
descriptor.configurable = true;
|
|
20
|
-
if ("value" in descriptor) descriptor.writable = true;
|
|
21
|
-
Object.defineProperty(target, descriptor.key, descriptor);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function _createClass(Constructor, protoProps, staticProps) {
|
|
26
|
-
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
27
|
-
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
28
|
-
return Constructor;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
9
|
/**
|
|
32
10
|
* A bounding box has the format:
|
|
33
11
|
*
|
|
34
12
|
* { ll: { x: xmin, y: ymin }, ur: { x: xmax, y: ymax } }
|
|
35
13
|
*
|
|
36
14
|
*/
|
|
37
|
-
|
|
15
|
+
|
|
16
|
+
const isInBbox = (bbox, point) => {
|
|
38
17
|
return bbox.ll.x <= point.x && point.x <= bbox.ur.x && bbox.ll.y <= point.y && point.y <= bbox.ur.y;
|
|
39
18
|
};
|
|
19
|
+
|
|
40
20
|
/* Returns either null, or a bbox (aka an ordered pair of points)
|
|
41
21
|
* If there is only one point of overlap, a bbox with identical points
|
|
42
22
|
* will be returned */
|
|
43
|
-
|
|
44
|
-
var getBboxOverlap = function getBboxOverlap(b1, b2) {
|
|
23
|
+
const getBboxOverlap = (b1, b2) => {
|
|
45
24
|
// check if the bboxes overlap at all
|
|
46
|
-
if (b2.ur.x < b1.ll.x || b1.ur.x < b2.ll.x || b2.ur.y < b1.ll.y || b1.ur.y < b2.ll.y) return null;
|
|
25
|
+
if (b2.ur.x < b1.ll.x || b1.ur.x < b2.ll.x || b2.ur.y < b1.ll.y || b1.ur.y < b2.ll.y) return null;
|
|
47
26
|
|
|
48
|
-
|
|
49
|
-
|
|
27
|
+
// find the middle two X values
|
|
28
|
+
const lowerX = b1.ll.x < b2.ll.x ? b2.ll.x : b1.ll.x;
|
|
29
|
+
const upperX = b1.ur.x < b2.ur.x ? b1.ur.x : b2.ur.x;
|
|
50
30
|
|
|
51
|
-
|
|
52
|
-
|
|
31
|
+
// find the middle two Y values
|
|
32
|
+
const lowerY = b1.ll.y < b2.ll.y ? b2.ll.y : b1.ll.y;
|
|
33
|
+
const upperY = b1.ur.y < b2.ur.y ? b1.ur.y : b2.ur.y;
|
|
53
34
|
|
|
35
|
+
// put those middle values together to get the overlap
|
|
54
36
|
return {
|
|
55
37
|
ll: {
|
|
56
38
|
x: lowerX,
|
|
@@ -68,28 +50,29 @@ var getBboxOverlap = function getBboxOverlap(b1, b2) {
|
|
|
68
50
|
*
|
|
69
51
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON
|
|
70
52
|
*/
|
|
71
|
-
var epsilon = Number.EPSILON; // IE Polyfill
|
|
72
53
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
54
|
+
let epsilon$1 = Number.EPSILON;
|
|
55
|
+
|
|
56
|
+
// IE Polyfill
|
|
57
|
+
if (epsilon$1 === undefined) epsilon$1 = Math.pow(2, -52);
|
|
58
|
+
const EPSILON_SQ = epsilon$1 * epsilon$1;
|
|
76
59
|
|
|
77
|
-
|
|
60
|
+
/* FLP comparator */
|
|
61
|
+
const cmp = (a, b) => {
|
|
78
62
|
// check if they're both 0
|
|
79
|
-
if (-epsilon < a && a < epsilon) {
|
|
80
|
-
if (-epsilon < b && b < epsilon) {
|
|
63
|
+
if (-epsilon$1 < a && a < epsilon$1) {
|
|
64
|
+
if (-epsilon$1 < b && b < epsilon$1) {
|
|
81
65
|
return 0;
|
|
82
66
|
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
var ab = a - b;
|
|
67
|
+
}
|
|
87
68
|
|
|
69
|
+
// check if they're flp equal
|
|
70
|
+
const ab = a - b;
|
|
88
71
|
if (ab * ab < EPSILON_SQ * a * b) {
|
|
89
72
|
return 0;
|
|
90
|
-
}
|
|
91
|
-
|
|
73
|
+
}
|
|
92
74
|
|
|
75
|
+
// normal comparison
|
|
93
76
|
return a < b ? -1 : 1;
|
|
94
77
|
};
|
|
95
78
|
|
|
@@ -106,467 +89,680 @@ var cmp = function cmp(a, b) {
|
|
|
106
89
|
* stored in any data structures in the rest of this algorithm.
|
|
107
90
|
*/
|
|
108
91
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
_classCallCheck(this, PtRounder);
|
|
112
|
-
|
|
92
|
+
class PtRounder {
|
|
93
|
+
constructor() {
|
|
113
94
|
this.reset();
|
|
114
95
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}]);
|
|
131
|
-
|
|
132
|
-
return PtRounder;
|
|
133
|
-
}();
|
|
134
|
-
|
|
135
|
-
var CoordRounder = /*#__PURE__*/function () {
|
|
136
|
-
function CoordRounder() {
|
|
137
|
-
_classCallCheck(this, CoordRounder);
|
|
138
|
-
|
|
139
|
-
this.tree = new SplayTree__default['default'](); // preseed with 0 so we don't end up with values < Number.EPSILON
|
|
140
|
-
|
|
96
|
+
reset() {
|
|
97
|
+
this.xRounder = new CoordRounder();
|
|
98
|
+
this.yRounder = new CoordRounder();
|
|
99
|
+
}
|
|
100
|
+
round(x, y) {
|
|
101
|
+
return {
|
|
102
|
+
x: this.xRounder.round(x),
|
|
103
|
+
y: this.yRounder.round(y)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
class CoordRounder {
|
|
108
|
+
constructor() {
|
|
109
|
+
this.tree = new SplayTree__default["default"]();
|
|
110
|
+
// preseed with 0 so we don't end up with values < Number.EPSILON
|
|
141
111
|
this.round(0);
|
|
142
|
-
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Note: this can rounds input values backwards or forwards.
|
|
143
115
|
// You might ask, why not restrict this to just rounding
|
|
144
116
|
// forwards? Wouldn't that allow left endpoints to always
|
|
145
117
|
// remain left endpoints during splitting (never change to
|
|
146
118
|
// right). No - it wouldn't, because we snap intersections
|
|
147
119
|
// to endpoints (to establish independence from the segment
|
|
148
120
|
// angle for t-intersections).
|
|
121
|
+
round(coord) {
|
|
122
|
+
const node = this.tree.add(coord);
|
|
123
|
+
const prevNode = this.tree.prev(node);
|
|
124
|
+
if (prevNode !== null && cmp(node.key, prevNode.key) === 0) {
|
|
125
|
+
this.tree.remove(coord);
|
|
126
|
+
return prevNode.key;
|
|
127
|
+
}
|
|
128
|
+
const nextNode = this.tree.next(node);
|
|
129
|
+
if (nextNode !== null && cmp(node.key, nextNode.key) === 0) {
|
|
130
|
+
this.tree.remove(coord);
|
|
131
|
+
return nextNode.key;
|
|
132
|
+
}
|
|
133
|
+
return coord;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
149
136
|
|
|
137
|
+
// singleton available by import
|
|
138
|
+
const rounder = new PtRounder();
|
|
139
|
+
|
|
140
|
+
const epsilon = 1.1102230246251565e-16;
|
|
141
|
+
const splitter = 134217729;
|
|
142
|
+
const resulterrbound = (3 + 8 * epsilon) * epsilon;
|
|
143
|
+
|
|
144
|
+
// fast_expansion_sum_zeroelim routine from oritinal code
|
|
145
|
+
function sum(elen, e, flen, f, h) {
|
|
146
|
+
let Q, Qnew, hh, bvirt;
|
|
147
|
+
let enow = e[0];
|
|
148
|
+
let fnow = f[0];
|
|
149
|
+
let eindex = 0;
|
|
150
|
+
let findex = 0;
|
|
151
|
+
if ((fnow > enow) === (fnow > -enow)) {
|
|
152
|
+
Q = enow;
|
|
153
|
+
enow = e[++eindex];
|
|
154
|
+
} else {
|
|
155
|
+
Q = fnow;
|
|
156
|
+
fnow = f[++findex];
|
|
157
|
+
}
|
|
158
|
+
let hindex = 0;
|
|
159
|
+
if (eindex < elen && findex < flen) {
|
|
160
|
+
if ((fnow > enow) === (fnow > -enow)) {
|
|
161
|
+
Qnew = enow + Q;
|
|
162
|
+
hh = Q - (Qnew - enow);
|
|
163
|
+
enow = e[++eindex];
|
|
164
|
+
} else {
|
|
165
|
+
Qnew = fnow + Q;
|
|
166
|
+
hh = Q - (Qnew - fnow);
|
|
167
|
+
fnow = f[++findex];
|
|
168
|
+
}
|
|
169
|
+
Q = Qnew;
|
|
170
|
+
if (hh !== 0) {
|
|
171
|
+
h[hindex++] = hh;
|
|
172
|
+
}
|
|
173
|
+
while (eindex < elen && findex < flen) {
|
|
174
|
+
if ((fnow > enow) === (fnow > -enow)) {
|
|
175
|
+
Qnew = Q + enow;
|
|
176
|
+
bvirt = Qnew - Q;
|
|
177
|
+
hh = Q - (Qnew - bvirt) + (enow - bvirt);
|
|
178
|
+
enow = e[++eindex];
|
|
179
|
+
} else {
|
|
180
|
+
Qnew = Q + fnow;
|
|
181
|
+
bvirt = Qnew - Q;
|
|
182
|
+
hh = Q - (Qnew - bvirt) + (fnow - bvirt);
|
|
183
|
+
fnow = f[++findex];
|
|
184
|
+
}
|
|
185
|
+
Q = Qnew;
|
|
186
|
+
if (hh !== 0) {
|
|
187
|
+
h[hindex++] = hh;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
while (eindex < elen) {
|
|
192
|
+
Qnew = Q + enow;
|
|
193
|
+
bvirt = Qnew - Q;
|
|
194
|
+
hh = Q - (Qnew - bvirt) + (enow - bvirt);
|
|
195
|
+
enow = e[++eindex];
|
|
196
|
+
Q = Qnew;
|
|
197
|
+
if (hh !== 0) {
|
|
198
|
+
h[hindex++] = hh;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
while (findex < flen) {
|
|
202
|
+
Qnew = Q + fnow;
|
|
203
|
+
bvirt = Qnew - Q;
|
|
204
|
+
hh = Q - (Qnew - bvirt) + (fnow - bvirt);
|
|
205
|
+
fnow = f[++findex];
|
|
206
|
+
Q = Qnew;
|
|
207
|
+
if (hh !== 0) {
|
|
208
|
+
h[hindex++] = hh;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (Q !== 0 || hindex === 0) {
|
|
212
|
+
h[hindex++] = Q;
|
|
213
|
+
}
|
|
214
|
+
return hindex;
|
|
215
|
+
}
|
|
150
216
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (prevNode !== null && cmp(node.key, prevNode.key) === 0) {
|
|
158
|
-
this.tree.remove(coord);
|
|
159
|
-
return prevNode.key;
|
|
160
|
-
}
|
|
217
|
+
function estimate(elen, e) {
|
|
218
|
+
let Q = e[0];
|
|
219
|
+
for (let i = 1; i < elen; i++) Q += e[i];
|
|
220
|
+
return Q;
|
|
221
|
+
}
|
|
161
222
|
|
|
162
|
-
|
|
223
|
+
function vec(n) {
|
|
224
|
+
return new Float64Array(n);
|
|
225
|
+
}
|
|
163
226
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
227
|
+
const ccwerrboundA = (3 + 16 * epsilon) * epsilon;
|
|
228
|
+
const ccwerrboundB = (2 + 12 * epsilon) * epsilon;
|
|
229
|
+
const ccwerrboundC = (9 + 64 * epsilon) * epsilon * epsilon;
|
|
230
|
+
|
|
231
|
+
const B = vec(4);
|
|
232
|
+
const C1 = vec(8);
|
|
233
|
+
const C2 = vec(12);
|
|
234
|
+
const D = vec(16);
|
|
235
|
+
const u = vec(4);
|
|
236
|
+
|
|
237
|
+
function orient2dadapt(ax, ay, bx, by, cx, cy, detsum) {
|
|
238
|
+
let acxtail, acytail, bcxtail, bcytail;
|
|
239
|
+
let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u3;
|
|
240
|
+
|
|
241
|
+
const acx = ax - cx;
|
|
242
|
+
const bcx = bx - cx;
|
|
243
|
+
const acy = ay - cy;
|
|
244
|
+
const bcy = by - cy;
|
|
245
|
+
|
|
246
|
+
s1 = acx * bcy;
|
|
247
|
+
c = splitter * acx;
|
|
248
|
+
ahi = c - (c - acx);
|
|
249
|
+
alo = acx - ahi;
|
|
250
|
+
c = splitter * bcy;
|
|
251
|
+
bhi = c - (c - bcy);
|
|
252
|
+
blo = bcy - bhi;
|
|
253
|
+
s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
|
|
254
|
+
t1 = acy * bcx;
|
|
255
|
+
c = splitter * acy;
|
|
256
|
+
ahi = c - (c - acy);
|
|
257
|
+
alo = acy - ahi;
|
|
258
|
+
c = splitter * bcx;
|
|
259
|
+
bhi = c - (c - bcx);
|
|
260
|
+
blo = bcx - bhi;
|
|
261
|
+
t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
|
|
262
|
+
_i = s0 - t0;
|
|
263
|
+
bvirt = s0 - _i;
|
|
264
|
+
B[0] = s0 - (_i + bvirt) + (bvirt - t0);
|
|
265
|
+
_j = s1 + _i;
|
|
266
|
+
bvirt = _j - s1;
|
|
267
|
+
_0 = s1 - (_j - bvirt) + (_i - bvirt);
|
|
268
|
+
_i = _0 - t1;
|
|
269
|
+
bvirt = _0 - _i;
|
|
270
|
+
B[1] = _0 - (_i + bvirt) + (bvirt - t1);
|
|
271
|
+
u3 = _j + _i;
|
|
272
|
+
bvirt = u3 - _j;
|
|
273
|
+
B[2] = _j - (u3 - bvirt) + (_i - bvirt);
|
|
274
|
+
B[3] = u3;
|
|
275
|
+
|
|
276
|
+
let det = estimate(4, B);
|
|
277
|
+
let errbound = ccwerrboundB * detsum;
|
|
278
|
+
if (det >= errbound || -det >= errbound) {
|
|
279
|
+
return det;
|
|
280
|
+
}
|
|
168
281
|
|
|
169
|
-
|
|
282
|
+
bvirt = ax - acx;
|
|
283
|
+
acxtail = ax - (acx + bvirt) + (bvirt - cx);
|
|
284
|
+
bvirt = bx - bcx;
|
|
285
|
+
bcxtail = bx - (bcx + bvirt) + (bvirt - cx);
|
|
286
|
+
bvirt = ay - acy;
|
|
287
|
+
acytail = ay - (acy + bvirt) + (bvirt - cy);
|
|
288
|
+
bvirt = by - bcy;
|
|
289
|
+
bcytail = by - (bcy + bvirt) + (bvirt - cy);
|
|
290
|
+
|
|
291
|
+
if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) {
|
|
292
|
+
return det;
|
|
170
293
|
}
|
|
171
|
-
}]);
|
|
172
294
|
|
|
173
|
-
|
|
174
|
-
|
|
295
|
+
errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det);
|
|
296
|
+
det += (acx * bcytail + bcy * acxtail) - (acy * bcxtail + bcx * acytail);
|
|
297
|
+
if (det >= errbound || -det >= errbound) return det;
|
|
298
|
+
|
|
299
|
+
s1 = acxtail * bcy;
|
|
300
|
+
c = splitter * acxtail;
|
|
301
|
+
ahi = c - (c - acxtail);
|
|
302
|
+
alo = acxtail - ahi;
|
|
303
|
+
c = splitter * bcy;
|
|
304
|
+
bhi = c - (c - bcy);
|
|
305
|
+
blo = bcy - bhi;
|
|
306
|
+
s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
|
|
307
|
+
t1 = acytail * bcx;
|
|
308
|
+
c = splitter * acytail;
|
|
309
|
+
ahi = c - (c - acytail);
|
|
310
|
+
alo = acytail - ahi;
|
|
311
|
+
c = splitter * bcx;
|
|
312
|
+
bhi = c - (c - bcx);
|
|
313
|
+
blo = bcx - bhi;
|
|
314
|
+
t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
|
|
315
|
+
_i = s0 - t0;
|
|
316
|
+
bvirt = s0 - _i;
|
|
317
|
+
u[0] = s0 - (_i + bvirt) + (bvirt - t0);
|
|
318
|
+
_j = s1 + _i;
|
|
319
|
+
bvirt = _j - s1;
|
|
320
|
+
_0 = s1 - (_j - bvirt) + (_i - bvirt);
|
|
321
|
+
_i = _0 - t1;
|
|
322
|
+
bvirt = _0 - _i;
|
|
323
|
+
u[1] = _0 - (_i + bvirt) + (bvirt - t1);
|
|
324
|
+
u3 = _j + _i;
|
|
325
|
+
bvirt = u3 - _j;
|
|
326
|
+
u[2] = _j - (u3 - bvirt) + (_i - bvirt);
|
|
327
|
+
u[3] = u3;
|
|
328
|
+
const C1len = sum(4, B, 4, u, C1);
|
|
329
|
+
|
|
330
|
+
s1 = acx * bcytail;
|
|
331
|
+
c = splitter * acx;
|
|
332
|
+
ahi = c - (c - acx);
|
|
333
|
+
alo = acx - ahi;
|
|
334
|
+
c = splitter * bcytail;
|
|
335
|
+
bhi = c - (c - bcytail);
|
|
336
|
+
blo = bcytail - bhi;
|
|
337
|
+
s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
|
|
338
|
+
t1 = acy * bcxtail;
|
|
339
|
+
c = splitter * acy;
|
|
340
|
+
ahi = c - (c - acy);
|
|
341
|
+
alo = acy - ahi;
|
|
342
|
+
c = splitter * bcxtail;
|
|
343
|
+
bhi = c - (c - bcxtail);
|
|
344
|
+
blo = bcxtail - bhi;
|
|
345
|
+
t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
|
|
346
|
+
_i = s0 - t0;
|
|
347
|
+
bvirt = s0 - _i;
|
|
348
|
+
u[0] = s0 - (_i + bvirt) + (bvirt - t0);
|
|
349
|
+
_j = s1 + _i;
|
|
350
|
+
bvirt = _j - s1;
|
|
351
|
+
_0 = s1 - (_j - bvirt) + (_i - bvirt);
|
|
352
|
+
_i = _0 - t1;
|
|
353
|
+
bvirt = _0 - _i;
|
|
354
|
+
u[1] = _0 - (_i + bvirt) + (bvirt - t1);
|
|
355
|
+
u3 = _j + _i;
|
|
356
|
+
bvirt = u3 - _j;
|
|
357
|
+
u[2] = _j - (u3 - bvirt) + (_i - bvirt);
|
|
358
|
+
u[3] = u3;
|
|
359
|
+
const C2len = sum(C1len, C1, 4, u, C2);
|
|
360
|
+
|
|
361
|
+
s1 = acxtail * bcytail;
|
|
362
|
+
c = splitter * acxtail;
|
|
363
|
+
ahi = c - (c - acxtail);
|
|
364
|
+
alo = acxtail - ahi;
|
|
365
|
+
c = splitter * bcytail;
|
|
366
|
+
bhi = c - (c - bcytail);
|
|
367
|
+
blo = bcytail - bhi;
|
|
368
|
+
s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);
|
|
369
|
+
t1 = acytail * bcxtail;
|
|
370
|
+
c = splitter * acytail;
|
|
371
|
+
ahi = c - (c - acytail);
|
|
372
|
+
alo = acytail - ahi;
|
|
373
|
+
c = splitter * bcxtail;
|
|
374
|
+
bhi = c - (c - bcxtail);
|
|
375
|
+
blo = bcxtail - bhi;
|
|
376
|
+
t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);
|
|
377
|
+
_i = s0 - t0;
|
|
378
|
+
bvirt = s0 - _i;
|
|
379
|
+
u[0] = s0 - (_i + bvirt) + (bvirt - t0);
|
|
380
|
+
_j = s1 + _i;
|
|
381
|
+
bvirt = _j - s1;
|
|
382
|
+
_0 = s1 - (_j - bvirt) + (_i - bvirt);
|
|
383
|
+
_i = _0 - t1;
|
|
384
|
+
bvirt = _0 - _i;
|
|
385
|
+
u[1] = _0 - (_i + bvirt) + (bvirt - t1);
|
|
386
|
+
u3 = _j + _i;
|
|
387
|
+
bvirt = u3 - _j;
|
|
388
|
+
u[2] = _j - (u3 - bvirt) + (_i - bvirt);
|
|
389
|
+
u[3] = u3;
|
|
390
|
+
const Dlen = sum(C2len, C2, 4, u, D);
|
|
391
|
+
|
|
392
|
+
return D[Dlen - 1];
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function orient2d(ax, ay, bx, by, cx, cy) {
|
|
396
|
+
const detleft = (ay - cy) * (bx - cx);
|
|
397
|
+
const detright = (ax - cx) * (by - cy);
|
|
398
|
+
const det = detleft - detright;
|
|
175
399
|
|
|
400
|
+
const detsum = Math.abs(detleft + detright);
|
|
401
|
+
if (Math.abs(det) >= ccwerrboundA * detsum) return det;
|
|
176
402
|
|
|
177
|
-
|
|
403
|
+
return -orient2dadapt(ax, ay, bx, by, cx, cy, detsum);
|
|
404
|
+
}
|
|
178
405
|
|
|
179
406
|
/* Cross Product of two vectors with first point at origin */
|
|
407
|
+
const crossProduct = (a, b) => a.x * b.y - a.y * b.x;
|
|
180
408
|
|
|
181
|
-
var crossProduct = function crossProduct(a, b) {
|
|
182
|
-
return a.x * b.y - a.y * b.x;
|
|
183
|
-
};
|
|
184
409
|
/* Dot Product of two vectors with first point at origin */
|
|
410
|
+
const dotProduct = (a, b) => a.x * b.x + a.y * b.y;
|
|
185
411
|
|
|
186
|
-
var dotProduct = function dotProduct(a, b) {
|
|
187
|
-
return a.x * b.x + a.y * b.y;
|
|
188
|
-
};
|
|
189
412
|
/* Comparator for two vectors with same starting point */
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
};
|
|
196
|
-
var v2 = {
|
|
197
|
-
x: endPt2.x - basePt.x,
|
|
198
|
-
y: endPt2.y - basePt.y
|
|
199
|
-
};
|
|
200
|
-
var kross = crossProduct(v1, v2);
|
|
201
|
-
return cmp(kross, 0);
|
|
413
|
+
const compareVectorAngles = (basePt, endPt1, endPt2) => {
|
|
414
|
+
const res = orient2d(basePt.x, basePt.y, endPt1.x, endPt1.y, endPt2.x, endPt2.y);
|
|
415
|
+
if (res > 0) return -1;
|
|
416
|
+
if (res < 0) return 1;
|
|
417
|
+
return 0;
|
|
202
418
|
};
|
|
203
|
-
|
|
204
|
-
return Math.sqrt(dotProduct(v, v));
|
|
205
|
-
};
|
|
206
|
-
/* Get the sine of the angle from pShared -> pAngle to pShaed -> pBase */
|
|
419
|
+
const length = v => Math.sqrt(dotProduct(v, v));
|
|
207
420
|
|
|
208
|
-
|
|
209
|
-
|
|
421
|
+
/* Get the sine of the angle from pShared -> pAngle to pShaed -> pBase */
|
|
422
|
+
const sineOfAngle = (pShared, pBase, pAngle) => {
|
|
423
|
+
const vBase = {
|
|
210
424
|
x: pBase.x - pShared.x,
|
|
211
425
|
y: pBase.y - pShared.y
|
|
212
426
|
};
|
|
213
|
-
|
|
427
|
+
const vAngle = {
|
|
214
428
|
x: pAngle.x - pShared.x,
|
|
215
429
|
y: pAngle.y - pShared.y
|
|
216
430
|
};
|
|
217
431
|
return crossProduct(vAngle, vBase) / length(vAngle) / length(vBase);
|
|
218
432
|
};
|
|
219
|
-
/* Get the cosine of the angle from pShared -> pAngle to pShaed -> pBase */
|
|
220
433
|
|
|
221
|
-
|
|
222
|
-
|
|
434
|
+
/* Get the cosine of the angle from pShared -> pAngle to pShaed -> pBase */
|
|
435
|
+
const cosineOfAngle = (pShared, pBase, pAngle) => {
|
|
436
|
+
const vBase = {
|
|
223
437
|
x: pBase.x - pShared.x,
|
|
224
438
|
y: pBase.y - pShared.y
|
|
225
439
|
};
|
|
226
|
-
|
|
440
|
+
const vAngle = {
|
|
227
441
|
x: pAngle.x - pShared.x,
|
|
228
442
|
y: pAngle.y - pShared.y
|
|
229
443
|
};
|
|
230
444
|
return dotProduct(vAngle, vBase) / length(vAngle) / length(vBase);
|
|
231
445
|
};
|
|
446
|
+
|
|
232
447
|
/* Get the x coordinate where the given line (defined by a point and vector)
|
|
233
448
|
* crosses the horizontal line with the given y coordiante.
|
|
234
449
|
* In the case of parrallel lines (including overlapping ones) returns null. */
|
|
235
|
-
|
|
236
|
-
var horizontalIntersection = function horizontalIntersection(pt, v, y) {
|
|
450
|
+
const horizontalIntersection = (pt, v, y) => {
|
|
237
451
|
if (v.y === 0) return null;
|
|
238
452
|
return {
|
|
239
453
|
x: pt.x + v.x / v.y * (y - pt.y),
|
|
240
454
|
y: y
|
|
241
455
|
};
|
|
242
456
|
};
|
|
457
|
+
|
|
243
458
|
/* Get the y coordinate where the given line (defined by a point and vector)
|
|
244
459
|
* crosses the vertical line with the given x coordiante.
|
|
245
460
|
* In the case of parrallel lines (including overlapping ones) returns null. */
|
|
246
|
-
|
|
247
|
-
var verticalIntersection = function verticalIntersection(pt, v, x) {
|
|
461
|
+
const verticalIntersection = (pt, v, x) => {
|
|
248
462
|
if (v.x === 0) return null;
|
|
249
463
|
return {
|
|
250
464
|
x: x,
|
|
251
465
|
y: pt.y + v.y / v.x * (x - pt.x)
|
|
252
466
|
};
|
|
253
467
|
};
|
|
468
|
+
|
|
254
469
|
/* Get the intersection of two lines, each defined by a base point and a vector.
|
|
255
470
|
* In the case of parrallel lines (including overlapping ones) returns null. */
|
|
256
|
-
|
|
257
|
-
var intersection = function intersection(pt1, v1, pt2, v2) {
|
|
471
|
+
const intersection$1 = (pt1, v1, pt2, v2) => {
|
|
258
472
|
// take some shortcuts for vertical and horizontal lines
|
|
259
473
|
// this also ensures we don't calculate an intersection and then discover
|
|
260
474
|
// it's actually outside the bounding box of the line
|
|
261
475
|
if (v1.x === 0) return verticalIntersection(pt2, v2, pt1.x);
|
|
262
476
|
if (v2.x === 0) return verticalIntersection(pt1, v1, pt2.x);
|
|
263
477
|
if (v1.y === 0) return horizontalIntersection(pt2, v2, pt1.y);
|
|
264
|
-
if (v2.y === 0) return horizontalIntersection(pt1, v1, pt2.y);
|
|
478
|
+
if (v2.y === 0) return horizontalIntersection(pt1, v1, pt2.y);
|
|
479
|
+
|
|
480
|
+
// General case for non-overlapping segments.
|
|
265
481
|
// This algorithm is based on Schneider and Eberly.
|
|
266
482
|
// http://www.cimec.org.ar/~ncalvo/Schneider_Eberly.pdf - pg 244
|
|
267
483
|
|
|
268
|
-
|
|
484
|
+
const kross = crossProduct(v1, v2);
|
|
269
485
|
if (kross == 0) return null;
|
|
270
|
-
|
|
486
|
+
const ve = {
|
|
271
487
|
x: pt2.x - pt1.x,
|
|
272
488
|
y: pt2.y - pt1.y
|
|
273
489
|
};
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
490
|
+
const d1 = crossProduct(ve, v1) / kross;
|
|
491
|
+
const d2 = crossProduct(ve, v2) / kross;
|
|
492
|
+
|
|
493
|
+
// take the average of the two calculations to minimize rounding error
|
|
494
|
+
const x1 = pt1.x + d2 * v1.x,
|
|
495
|
+
x2 = pt2.x + d1 * v2.x;
|
|
496
|
+
const y1 = pt1.y + d2 * v1.y,
|
|
497
|
+
y2 = pt2.y + d1 * v2.y;
|
|
498
|
+
const x = (x1 + x2) / 2;
|
|
499
|
+
const y = (y1 + y2) / 2;
|
|
283
500
|
return {
|
|
284
501
|
x: x,
|
|
285
502
|
y: y
|
|
286
503
|
};
|
|
287
504
|
};
|
|
288
505
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
//
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
var ptCmp = SweepEvent.comparePoints(a.point, b.point);
|
|
296
|
-
if (ptCmp !== 0) return ptCmp; // the points are the same, so link them if needed
|
|
297
|
-
|
|
298
|
-
if (a.point !== b.point) a.link(b); // favor right events over left
|
|
299
|
-
|
|
300
|
-
if (a.isLeft !== b.isLeft) return a.isLeft ? 1 : -1; // we have two matching left or right endpoints
|
|
301
|
-
// ordering of this case is the same as for their segments
|
|
302
|
-
|
|
303
|
-
return Segment.compare(a.segment, b.segment);
|
|
304
|
-
} // for ordering points in sweep line order
|
|
305
|
-
|
|
306
|
-
}, {
|
|
307
|
-
key: "comparePoints",
|
|
308
|
-
value: function comparePoints(aPt, bPt) {
|
|
309
|
-
if (aPt.x < bPt.x) return -1;
|
|
310
|
-
if (aPt.x > bPt.x) return 1;
|
|
311
|
-
if (aPt.y < bPt.y) return -1;
|
|
312
|
-
if (aPt.y > bPt.y) return 1;
|
|
313
|
-
return 0;
|
|
314
|
-
} // Warning: 'point' input will be modified and re-used (for performance)
|
|
506
|
+
class SweepEvent {
|
|
507
|
+
// for ordering sweep events in the sweep event queue
|
|
508
|
+
static compare(a, b) {
|
|
509
|
+
// favor event with a point that the sweep line hits first
|
|
510
|
+
const ptCmp = SweepEvent.comparePoints(a.point, b.point);
|
|
511
|
+
if (ptCmp !== 0) return ptCmp;
|
|
315
512
|
|
|
316
|
-
|
|
513
|
+
// the points are the same, so link them if needed
|
|
514
|
+
if (a.point !== b.point) a.link(b);
|
|
317
515
|
|
|
318
|
-
|
|
319
|
-
|
|
516
|
+
// favor right events over left
|
|
517
|
+
if (a.isLeft !== b.isLeft) return a.isLeft ? 1 : -1;
|
|
320
518
|
|
|
321
|
-
|
|
322
|
-
this
|
|
323
|
-
|
|
519
|
+
// we have two matching left or right endpoints
|
|
520
|
+
// ordering of this case is the same as for their segments
|
|
521
|
+
return Segment.compare(a.segment, b.segment);
|
|
324
522
|
}
|
|
325
523
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
524
|
+
// for ordering points in sweep line order
|
|
525
|
+
static comparePoints(aPt, bPt) {
|
|
526
|
+
if (aPt.x < bPt.x) return -1;
|
|
527
|
+
if (aPt.x > bPt.x) return 1;
|
|
528
|
+
if (aPt.y < bPt.y) return -1;
|
|
529
|
+
if (aPt.y > bPt.y) return 1;
|
|
530
|
+
return 0;
|
|
531
|
+
}
|
|
334
532
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
533
|
+
// Warning: 'point' input will be modified and re-used (for performance)
|
|
534
|
+
constructor(point, isLeft) {
|
|
535
|
+
if (point.events === undefined) point.events = [this];else point.events.push(this);
|
|
536
|
+
this.point = point;
|
|
537
|
+
this.isLeft = isLeft;
|
|
538
|
+
// this.segment, this.otherSE set by factory
|
|
539
|
+
}
|
|
540
|
+
link(other) {
|
|
541
|
+
if (other.point === this.point) {
|
|
542
|
+
throw new Error("Tried to link already linked events");
|
|
543
|
+
}
|
|
544
|
+
const otherEvents = other.point.events;
|
|
545
|
+
for (let i = 0, iMax = otherEvents.length; i < iMax; i++) {
|
|
546
|
+
const evt = otherEvents[i];
|
|
547
|
+
this.point.events.push(evt);
|
|
548
|
+
evt.point = this.point;
|
|
549
|
+
}
|
|
550
|
+
this.checkForConsuming();
|
|
551
|
+
}
|
|
340
552
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
for (var j = i + 1; j < numEvents; j++) {
|
|
361
|
-
var evt2 = this.point.events[j];
|
|
362
|
-
if (evt2.consumedBy !== undefined) continue;
|
|
363
|
-
if (evt1.otherSE.point.events !== evt2.otherSE.point.events) continue;
|
|
364
|
-
evt1.segment.consume(evt2.segment);
|
|
365
|
-
}
|
|
553
|
+
/* Do a pass over our linked events and check to see if any pair
|
|
554
|
+
* of segments match, and should be consumed. */
|
|
555
|
+
checkForConsuming() {
|
|
556
|
+
// FIXME: The loops in this method run O(n^2) => no good.
|
|
557
|
+
// Maintain little ordered sweep event trees?
|
|
558
|
+
// Can we maintaining an ordering that avoids the need
|
|
559
|
+
// for the re-sorting with getLeftmostComparator in geom-out?
|
|
560
|
+
|
|
561
|
+
// Compare each pair of events to see if other events also match
|
|
562
|
+
const numEvents = this.point.events.length;
|
|
563
|
+
for (let i = 0; i < numEvents; i++) {
|
|
564
|
+
const evt1 = this.point.events[i];
|
|
565
|
+
if (evt1.segment.consumedBy !== undefined) continue;
|
|
566
|
+
for (let j = i + 1; j < numEvents; j++) {
|
|
567
|
+
const evt2 = this.point.events[j];
|
|
568
|
+
if (evt2.consumedBy !== undefined) continue;
|
|
569
|
+
if (evt1.otherSE.point.events !== evt2.otherSE.point.events) continue;
|
|
570
|
+
evt1.segment.consume(evt2.segment);
|
|
366
571
|
}
|
|
367
572
|
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
if (evt !== this && !evt.segment.ringOut && evt.segment.isInResult()) {
|
|
378
|
-
events.push(evt);
|
|
379
|
-
}
|
|
573
|
+
}
|
|
574
|
+
getAvailableLinkedEvents() {
|
|
575
|
+
// point.events is always of length 2 or greater
|
|
576
|
+
const events = [];
|
|
577
|
+
for (let i = 0, iMax = this.point.events.length; i < iMax; i++) {
|
|
578
|
+
const evt = this.point.events[i];
|
|
579
|
+
if (evt !== this && !evt.segment.ringOut && evt.segment.isInResult()) {
|
|
580
|
+
events.push(evt);
|
|
380
581
|
}
|
|
381
|
-
|
|
382
|
-
return events;
|
|
383
582
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
* favor the event that will give us the smallest left-side angle.
|
|
387
|
-
* All ring construction starts as low as possible heading to the right,
|
|
388
|
-
* so by always turning left as sharp as possible we'll get polygons
|
|
389
|
-
* without uncessary loops & holes.
|
|
390
|
-
*
|
|
391
|
-
* The comparator function has a compute cache such that it avoids
|
|
392
|
-
* re-computing already-computed values.
|
|
393
|
-
*/
|
|
394
|
-
|
|
395
|
-
}, {
|
|
396
|
-
key: "getLeftmostComparator",
|
|
397
|
-
value: function getLeftmostComparator(baseEvent) {
|
|
398
|
-
var _this = this;
|
|
399
|
-
|
|
400
|
-
var cache = new Map();
|
|
401
|
-
|
|
402
|
-
var fillCache = function fillCache(linkedEvent) {
|
|
403
|
-
var nextEvent = linkedEvent.otherSE;
|
|
404
|
-
cache.set(linkedEvent, {
|
|
405
|
-
sine: sineOfAngle(_this.point, baseEvent.point, nextEvent.point),
|
|
406
|
-
cosine: cosineOfAngle(_this.point, baseEvent.point, nextEvent.point)
|
|
407
|
-
});
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
return function (a, b) {
|
|
411
|
-
if (!cache.has(a)) fillCache(a);
|
|
412
|
-
if (!cache.has(b)) fillCache(b);
|
|
583
|
+
return events;
|
|
584
|
+
}
|
|
413
585
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
586
|
+
/**
|
|
587
|
+
* Returns a comparator function for sorting linked events that will
|
|
588
|
+
* favor the event that will give us the smallest left-side angle.
|
|
589
|
+
* All ring construction starts as low as possible heading to the right,
|
|
590
|
+
* so by always turning left as sharp as possible we'll get polygons
|
|
591
|
+
* without uncessary loops & holes.
|
|
592
|
+
*
|
|
593
|
+
* The comparator function has a compute cache such that it avoids
|
|
594
|
+
* re-computing already-computed values.
|
|
595
|
+
*/
|
|
596
|
+
getLeftmostComparator(baseEvent) {
|
|
597
|
+
const cache = new Map();
|
|
598
|
+
const fillCache = linkedEvent => {
|
|
599
|
+
const nextEvent = linkedEvent.otherSE;
|
|
600
|
+
cache.set(linkedEvent, {
|
|
601
|
+
sine: sineOfAngle(this.point, baseEvent.point, nextEvent.point),
|
|
602
|
+
cosine: cosineOfAngle(this.point, baseEvent.point, nextEvent.point)
|
|
603
|
+
});
|
|
604
|
+
};
|
|
605
|
+
return (a, b) => {
|
|
606
|
+
if (!cache.has(a)) fillCache(a);
|
|
607
|
+
if (!cache.has(b)) fillCache(b);
|
|
608
|
+
const {
|
|
609
|
+
sine: asine,
|
|
610
|
+
cosine: acosine
|
|
611
|
+
} = cache.get(a);
|
|
612
|
+
const {
|
|
613
|
+
sine: bsine,
|
|
614
|
+
cosine: bcosine
|
|
615
|
+
} = cache.get(b);
|
|
616
|
+
|
|
617
|
+
// both on or above x-axis
|
|
618
|
+
if (asine >= 0 && bsine >= 0) {
|
|
619
|
+
if (acosine < bcosine) return 1;
|
|
620
|
+
if (acosine > bcosine) return -1;
|
|
621
|
+
return 0;
|
|
622
|
+
}
|
|
417
623
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
624
|
+
// both below x-axis
|
|
625
|
+
if (asine < 0 && bsine < 0) {
|
|
626
|
+
if (acosine < bcosine) return -1;
|
|
627
|
+
if (acosine > bcosine) return 1;
|
|
628
|
+
return 0;
|
|
629
|
+
}
|
|
421
630
|
|
|
631
|
+
// one above x-axis, one below
|
|
632
|
+
if (bsine < asine) return -1;
|
|
633
|
+
if (bsine > asine) return 1;
|
|
634
|
+
return 0;
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
}
|
|
422
638
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
639
|
+
// Give segments unique ID's to get consistent sorting of
|
|
640
|
+
// segments and sweep events when all else is identical
|
|
641
|
+
let segmentId = 0;
|
|
642
|
+
class Segment {
|
|
643
|
+
/* This compare() function is for ordering segments in the sweep
|
|
644
|
+
* line tree, and does so according to the following criteria:
|
|
645
|
+
*
|
|
646
|
+
* Consider the vertical line that lies an infinestimal step to the
|
|
647
|
+
* right of the right-more of the two left endpoints of the input
|
|
648
|
+
* segments. Imagine slowly moving a point up from negative infinity
|
|
649
|
+
* in the increasing y direction. Which of the two segments will that
|
|
650
|
+
* point intersect first? That segment comes 'before' the other one.
|
|
651
|
+
*
|
|
652
|
+
* If neither segment would be intersected by such a line, (if one
|
|
653
|
+
* or more of the segments are vertical) then the line to be considered
|
|
654
|
+
* is directly on the right-more of the two left inputs.
|
|
655
|
+
*/
|
|
656
|
+
static compare(a, b) {
|
|
657
|
+
const alx = a.leftSE.point.x;
|
|
658
|
+
const blx = b.leftSE.point.x;
|
|
659
|
+
const arx = a.rightSE.point.x;
|
|
660
|
+
const brx = b.rightSE.point.x;
|
|
661
|
+
|
|
662
|
+
// check if they're even in the same vertical plane
|
|
663
|
+
if (brx < alx) return 1;
|
|
664
|
+
if (arx < blx) return -1;
|
|
665
|
+
const aly = a.leftSE.point.y;
|
|
666
|
+
const bly = b.leftSE.point.y;
|
|
667
|
+
const ary = a.rightSE.point.y;
|
|
668
|
+
const bry = b.rightSE.point.y;
|
|
669
|
+
|
|
670
|
+
// is left endpoint of segment B the right-more?
|
|
671
|
+
if (alx < blx) {
|
|
672
|
+
// are the two segments in the same horizontal plane?
|
|
673
|
+
if (bly < aly && bly < ary) return 1;
|
|
674
|
+
if (bly > aly && bly > ary) return -1;
|
|
675
|
+
|
|
676
|
+
// is the B left endpoint colinear to segment A?
|
|
677
|
+
const aCmpBLeft = a.comparePoint(b.leftSE.point);
|
|
678
|
+
if (aCmpBLeft < 0) return 1;
|
|
679
|
+
if (aCmpBLeft > 0) return -1;
|
|
680
|
+
|
|
681
|
+
// is the A right endpoint colinear to segment B ?
|
|
682
|
+
const bCmpARight = b.comparePoint(a.rightSE.point);
|
|
683
|
+
if (bCmpARight !== 0) return bCmpARight;
|
|
684
|
+
|
|
685
|
+
// colinear segments, consider the one with left-more
|
|
686
|
+
// left endpoint to be first (arbitrary?)
|
|
687
|
+
return -1;
|
|
688
|
+
}
|
|
428
689
|
|
|
690
|
+
// is left endpoint of segment A the right-more?
|
|
691
|
+
if (alx > blx) {
|
|
692
|
+
if (aly < bly && aly < bry) return -1;
|
|
693
|
+
if (aly > bly && aly > bry) return 1;
|
|
429
694
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
return 0;
|
|
434
|
-
} // one above x-axis, one below
|
|
695
|
+
// is the A left endpoint colinear to segment B?
|
|
696
|
+
const bCmpALeft = b.comparePoint(a.leftSE.point);
|
|
697
|
+
if (bCmpALeft !== 0) return bCmpALeft;
|
|
435
698
|
|
|
699
|
+
// is the B right endpoint colinear to segment A?
|
|
700
|
+
const aCmpBRight = a.comparePoint(b.rightSE.point);
|
|
701
|
+
if (aCmpBRight < 0) return 1;
|
|
702
|
+
if (aCmpBRight > 0) return -1;
|
|
436
703
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
};
|
|
704
|
+
// colinear segments, consider the one with left-more
|
|
705
|
+
// left endpoint to be first (arbitrary?)
|
|
706
|
+
return 1;
|
|
441
707
|
}
|
|
442
|
-
}]);
|
|
443
708
|
|
|
444
|
-
|
|
445
|
-
|
|
709
|
+
// if we get here, the two left endpoints are in the same
|
|
710
|
+
// vertical plane, ie alx === blx
|
|
446
711
|
|
|
447
|
-
//
|
|
712
|
+
// consider the lower left-endpoint to come first
|
|
713
|
+
if (aly < bly) return -1;
|
|
714
|
+
if (aly > bly) return 1;
|
|
448
715
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
var Segment = /*#__PURE__*/function () {
|
|
452
|
-
_createClass(Segment, null, [{
|
|
453
|
-
key: "compare",
|
|
454
|
-
|
|
455
|
-
/* This compare() function is for ordering segments in the sweep
|
|
456
|
-
* line tree, and does so according to the following criteria:
|
|
457
|
-
*
|
|
458
|
-
* Consider the vertical line that lies an infinestimal step to the
|
|
459
|
-
* right of the right-more of the two left endpoints of the input
|
|
460
|
-
* segments. Imagine slowly moving a point up from negative infinity
|
|
461
|
-
* in the increasing y direction. Which of the two segments will that
|
|
462
|
-
* point intersect first? That segment comes 'before' the other one.
|
|
463
|
-
*
|
|
464
|
-
* If neither segment would be intersected by such a line, (if one
|
|
465
|
-
* or more of the segments are vertical) then the line to be considered
|
|
466
|
-
* is directly on the right-more of the two left inputs.
|
|
467
|
-
*/
|
|
468
|
-
value: function compare(a, b) {
|
|
469
|
-
var alx = a.leftSE.point.x;
|
|
470
|
-
var blx = b.leftSE.point.x;
|
|
471
|
-
var arx = a.rightSE.point.x;
|
|
472
|
-
var brx = b.rightSE.point.x; // check if they're even in the same vertical plane
|
|
473
|
-
|
|
474
|
-
if (brx < alx) return 1;
|
|
475
|
-
if (arx < blx) return -1;
|
|
476
|
-
var aly = a.leftSE.point.y;
|
|
477
|
-
var bly = b.leftSE.point.y;
|
|
478
|
-
var ary = a.rightSE.point.y;
|
|
479
|
-
var bry = b.rightSE.point.y; // is left endpoint of segment B the right-more?
|
|
480
|
-
|
|
481
|
-
if (alx < blx) {
|
|
482
|
-
// are the two segments in the same horizontal plane?
|
|
483
|
-
if (bly < aly && bly < ary) return 1;
|
|
484
|
-
if (bly > aly && bly > ary) return -1; // is the B left endpoint colinear to segment A?
|
|
485
|
-
|
|
486
|
-
var aCmpBLeft = a.comparePoint(b.leftSE.point);
|
|
487
|
-
if (aCmpBLeft < 0) return 1;
|
|
488
|
-
if (aCmpBLeft > 0) return -1; // is the A right endpoint colinear to segment B ?
|
|
489
|
-
|
|
490
|
-
var bCmpARight = b.comparePoint(a.rightSE.point);
|
|
491
|
-
if (bCmpARight !== 0) return bCmpARight; // colinear segments, consider the one with left-more
|
|
492
|
-
// left endpoint to be first (arbitrary?)
|
|
493
|
-
|
|
494
|
-
return -1;
|
|
495
|
-
} // is left endpoint of segment A the right-more?
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
if (alx > blx) {
|
|
499
|
-
if (aly < bly && aly < bry) return -1;
|
|
500
|
-
if (aly > bly && aly > bry) return 1; // is the A left endpoint colinear to segment B?
|
|
501
|
-
|
|
502
|
-
var bCmpALeft = b.comparePoint(a.leftSE.point);
|
|
503
|
-
if (bCmpALeft !== 0) return bCmpALeft; // is the B right endpoint colinear to segment A?
|
|
504
|
-
|
|
505
|
-
var aCmpBRight = a.comparePoint(b.rightSE.point);
|
|
506
|
-
if (aCmpBRight < 0) return 1;
|
|
507
|
-
if (aCmpBRight > 0) return -1; // colinear segments, consider the one with left-more
|
|
508
|
-
// left endpoint to be first (arbitrary?)
|
|
509
|
-
|
|
510
|
-
return 1;
|
|
511
|
-
} // if we get here, the two left endpoints are in the same
|
|
512
|
-
// vertical plane, ie alx === blx
|
|
513
|
-
// consider the lower left-endpoint to come first
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
if (aly < bly) return -1;
|
|
517
|
-
if (aly > bly) return 1; // left endpoints are identical
|
|
518
|
-
// check for colinearity by using the left-more right endpoint
|
|
519
|
-
// is the A right endpoint more left-more?
|
|
520
|
-
|
|
521
|
-
if (arx < brx) {
|
|
522
|
-
var _bCmpARight = b.comparePoint(a.rightSE.point);
|
|
523
|
-
|
|
524
|
-
if (_bCmpARight !== 0) return _bCmpARight;
|
|
525
|
-
} // is the B right endpoint more left-more?
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (arx > brx) {
|
|
529
|
-
var _aCmpBRight = a.comparePoint(b.rightSE.point);
|
|
530
|
-
|
|
531
|
-
if (_aCmpBRight < 0) return 1;
|
|
532
|
-
if (_aCmpBRight > 0) return -1;
|
|
533
|
-
}
|
|
716
|
+
// left endpoints are identical
|
|
717
|
+
// check for colinearity by using the left-more right endpoint
|
|
534
718
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
var by = bry - bly;
|
|
541
|
-
var bx = brx - blx;
|
|
542
|
-
if (ay > ax && by < bx) return 1;
|
|
543
|
-
if (ay < ax && by > bx) return -1;
|
|
544
|
-
} // we have colinear segments with matching orientation
|
|
545
|
-
// consider the one with more left-more right endpoint to be first
|
|
719
|
+
// is the A right endpoint more left-more?
|
|
720
|
+
if (arx < brx) {
|
|
721
|
+
const bCmpARight = b.comparePoint(a.rightSE.point);
|
|
722
|
+
if (bCmpARight !== 0) return bCmpARight;
|
|
723
|
+
}
|
|
546
724
|
|
|
725
|
+
// is the B right endpoint more left-more?
|
|
726
|
+
if (arx > brx) {
|
|
727
|
+
const aCmpBRight = a.comparePoint(b.rightSE.point);
|
|
728
|
+
if (aCmpBRight < 0) return 1;
|
|
729
|
+
if (aCmpBRight > 0) return -1;
|
|
730
|
+
}
|
|
731
|
+
if (arx !== brx) {
|
|
732
|
+
// are these two [almost] vertical segments with opposite orientation?
|
|
733
|
+
// if so, the one with the lower right endpoint comes first
|
|
734
|
+
const ay = ary - aly;
|
|
735
|
+
const ax = arx - alx;
|
|
736
|
+
const by = bry - bly;
|
|
737
|
+
const bx = brx - blx;
|
|
738
|
+
if (ay > ax && by < bx) return 1;
|
|
739
|
+
if (ay < ax && by > bx) return -1;
|
|
740
|
+
}
|
|
547
741
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
742
|
+
// we have colinear segments with matching orientation
|
|
743
|
+
// consider the one with more left-more right endpoint to be first
|
|
744
|
+
if (arx > brx) return 1;
|
|
745
|
+
if (arx < brx) return -1;
|
|
552
746
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
// fall back on creation order as consistent tie-breaker
|
|
747
|
+
// if we get here, two two right endpoints are in the same
|
|
748
|
+
// vertical plane, ie arx === brx
|
|
556
749
|
|
|
557
|
-
|
|
558
|
-
|
|
750
|
+
// consider the lower right-endpoint to come first
|
|
751
|
+
if (ary < bry) return -1;
|
|
752
|
+
if (ary > bry) return 1;
|
|
559
753
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
754
|
+
// right endpoints identical as well, so the segments are idential
|
|
755
|
+
// fall back on creation order as consistent tie-breaker
|
|
756
|
+
if (a.id < b.id) return -1;
|
|
757
|
+
if (a.id > b.id) return 1;
|
|
564
758
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
_classCallCheck(this, Segment);
|
|
759
|
+
// identical segment, ie a === b
|
|
760
|
+
return 0;
|
|
761
|
+
}
|
|
569
762
|
|
|
763
|
+
/* Warning: a reference to ringWindings input will be stored,
|
|
764
|
+
* and possibly will be later modified */
|
|
765
|
+
constructor(leftSE, rightSE, rings, windings) {
|
|
570
766
|
this.id = ++segmentId;
|
|
571
767
|
this.leftSE = leftSE;
|
|
572
768
|
leftSE.segment = this;
|
|
@@ -575,481 +771,425 @@ var Segment = /*#__PURE__*/function () {
|
|
|
575
771
|
rightSE.segment = this;
|
|
576
772
|
rightSE.otherSE = leftSE;
|
|
577
773
|
this.rings = rings;
|
|
578
|
-
this.windings = windings;
|
|
774
|
+
this.windings = windings;
|
|
775
|
+
// left unset for performance, set later in algorithm
|
|
579
776
|
// this.ringOut, this.consumedBy, this.prev
|
|
580
777
|
}
|
|
778
|
+
static fromRing(pt1, pt2, ring) {
|
|
779
|
+
let leftPt, rightPt, winding;
|
|
780
|
+
|
|
781
|
+
// ordering the two points according to sweep line ordering
|
|
782
|
+
const cmpPts = SweepEvent.comparePoints(pt1, pt2);
|
|
783
|
+
if (cmpPts < 0) {
|
|
784
|
+
leftPt = pt1;
|
|
785
|
+
rightPt = pt2;
|
|
786
|
+
winding = 1;
|
|
787
|
+
} else if (cmpPts > 0) {
|
|
788
|
+
leftPt = pt2;
|
|
789
|
+
rightPt = pt1;
|
|
790
|
+
winding = -1;
|
|
791
|
+
} else throw new Error(`Tried to create degenerate segment at [${pt1.x}, ${pt1.y}]`);
|
|
792
|
+
const leftSE = new SweepEvent(leftPt, true);
|
|
793
|
+
const rightSE = new SweepEvent(rightPt, false);
|
|
794
|
+
return new Segment(leftSE, rightSE, [ring], [winding]);
|
|
795
|
+
}
|
|
581
796
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
y: y1 < y2 ? y1 : y2
|
|
601
|
-
},
|
|
602
|
-
ur: {
|
|
603
|
-
x: this.rightSE.point.x,
|
|
604
|
-
y: y1 > y2 ? y1 : y2
|
|
605
|
-
}
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
/* A vector from the left point to the right */
|
|
609
|
-
|
|
610
|
-
}, {
|
|
611
|
-
key: "vector",
|
|
612
|
-
value: function vector() {
|
|
613
|
-
return {
|
|
614
|
-
x: this.rightSE.point.x - this.leftSE.point.x,
|
|
615
|
-
y: this.rightSE.point.y - this.leftSE.point.y
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
}, {
|
|
619
|
-
key: "isAnEndpoint",
|
|
620
|
-
value: function isAnEndpoint(pt) {
|
|
621
|
-
return pt.x === this.leftSE.point.x && pt.y === this.leftSE.point.y || pt.x === this.rightSE.point.x && pt.y === this.rightSE.point.y;
|
|
622
|
-
}
|
|
623
|
-
/* Compare this segment with a point.
|
|
624
|
-
*
|
|
625
|
-
* A point P is considered to be colinear to a segment if there
|
|
626
|
-
* exists a distance D such that if we travel along the segment
|
|
627
|
-
* from one * endpoint towards the other a distance D, we find
|
|
628
|
-
* ourselves at point P.
|
|
629
|
-
*
|
|
630
|
-
* Return value indicates:
|
|
631
|
-
*
|
|
632
|
-
* 1: point lies above the segment (to the left of vertical)
|
|
633
|
-
* 0: point is colinear to segment
|
|
634
|
-
* -1: point lies below the segment (to the right of vertical)
|
|
635
|
-
*/
|
|
636
|
-
|
|
637
|
-
}, {
|
|
638
|
-
key: "comparePoint",
|
|
639
|
-
value: function comparePoint(point) {
|
|
640
|
-
if (this.isAnEndpoint(point)) return 0;
|
|
641
|
-
var lPt = this.leftSE.point;
|
|
642
|
-
var rPt = this.rightSE.point;
|
|
643
|
-
var v = this.vector(); // Exactly vertical segments.
|
|
644
|
-
|
|
645
|
-
if (lPt.x === rPt.x) {
|
|
646
|
-
if (point.x === lPt.x) return 0;
|
|
647
|
-
return point.x < lPt.x ? 1 : -1;
|
|
648
|
-
} // Nearly vertical segments with an intersection.
|
|
649
|
-
// Check to see where a point on the line with matching Y coordinate is.
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
var yDist = (point.y - lPt.y) / v.y;
|
|
653
|
-
var xFromYDist = lPt.x + yDist * v.x;
|
|
654
|
-
if (point.x === xFromYDist) return 0; // General case.
|
|
655
|
-
// Check to see where a point on the line with matching X coordinate is.
|
|
656
|
-
|
|
657
|
-
var xDist = (point.x - lPt.x) / v.x;
|
|
658
|
-
var yFromXDist = lPt.y + xDist * v.y;
|
|
659
|
-
if (point.y === yFromXDist) return 0;
|
|
660
|
-
return point.y < yFromXDist ? -1 : 1;
|
|
661
|
-
}
|
|
662
|
-
/**
|
|
663
|
-
* Given another segment, returns the first non-trivial intersection
|
|
664
|
-
* between the two segments (in terms of sweep line ordering), if it exists.
|
|
665
|
-
*
|
|
666
|
-
* A 'non-trivial' intersection is one that will cause one or both of the
|
|
667
|
-
* segments to be split(). As such, 'trivial' vs. 'non-trivial' intersection:
|
|
668
|
-
*
|
|
669
|
-
* * endpoint of segA with endpoint of segB --> trivial
|
|
670
|
-
* * endpoint of segA with point along segB --> non-trivial
|
|
671
|
-
* * endpoint of segB with point along segA --> non-trivial
|
|
672
|
-
* * point along segA with point along segB --> non-trivial
|
|
673
|
-
*
|
|
674
|
-
* If no non-trivial intersection exists, return null
|
|
675
|
-
* Else, return null.
|
|
676
|
-
*/
|
|
677
|
-
|
|
678
|
-
}, {
|
|
679
|
-
key: "getIntersection",
|
|
680
|
-
value: function getIntersection(other) {
|
|
681
|
-
// If bboxes don't overlap, there can't be any intersections
|
|
682
|
-
var tBbox = this.bbox();
|
|
683
|
-
var oBbox = other.bbox();
|
|
684
|
-
var bboxOverlap = getBboxOverlap(tBbox, oBbox);
|
|
685
|
-
if (bboxOverlap === null) return null; // We first check to see if the endpoints can be considered intersections.
|
|
686
|
-
// This will 'snap' intersections to endpoints if possible, and will
|
|
687
|
-
// handle cases of colinearity.
|
|
688
|
-
|
|
689
|
-
var tlp = this.leftSE.point;
|
|
690
|
-
var trp = this.rightSE.point;
|
|
691
|
-
var olp = other.leftSE.point;
|
|
692
|
-
var orp = other.rightSE.point; // does each endpoint touch the other segment?
|
|
693
|
-
// note that we restrict the 'touching' definition to only allow segments
|
|
694
|
-
// to touch endpoints that lie forward from where we are in the sweep line pass
|
|
695
|
-
|
|
696
|
-
var touchesOtherLSE = isInBbox(tBbox, olp) && this.comparePoint(olp) === 0;
|
|
697
|
-
var touchesThisLSE = isInBbox(oBbox, tlp) && other.comparePoint(tlp) === 0;
|
|
698
|
-
var touchesOtherRSE = isInBbox(tBbox, orp) && this.comparePoint(orp) === 0;
|
|
699
|
-
var touchesThisRSE = isInBbox(oBbox, trp) && other.comparePoint(trp) === 0; // do left endpoints match?
|
|
700
|
-
|
|
701
|
-
if (touchesThisLSE && touchesOtherLSE) {
|
|
702
|
-
// these two cases are for colinear segments with matching left
|
|
703
|
-
// endpoints, and one segment being longer than the other
|
|
704
|
-
if (touchesThisRSE && !touchesOtherRSE) return trp;
|
|
705
|
-
if (!touchesThisRSE && touchesOtherRSE) return orp; // either the two segments match exactly (two trival intersections)
|
|
706
|
-
// or just on their left endpoint (one trivial intersection
|
|
707
|
-
|
|
708
|
-
return null;
|
|
709
|
-
} // does this left endpoint matches (other doesn't)
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
if (touchesThisLSE) {
|
|
713
|
-
// check for segments that just intersect on opposing endpoints
|
|
714
|
-
if (touchesOtherRSE) {
|
|
715
|
-
if (tlp.x === orp.x && tlp.y === orp.y) return null;
|
|
716
|
-
} // t-intersection on left endpoint
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
return tlp;
|
|
720
|
-
} // does other left endpoint matches (this doesn't)
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
if (touchesOtherLSE) {
|
|
724
|
-
// check for segments that just intersect on opposing endpoints
|
|
725
|
-
if (touchesThisRSE) {
|
|
726
|
-
if (trp.x === olp.x && trp.y === olp.y) return null;
|
|
727
|
-
} // t-intersection on left endpoint
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
return olp;
|
|
731
|
-
} // trivial intersection on right endpoints
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
if (touchesThisRSE && touchesOtherRSE) return null; // t-intersections on just one right endpoint
|
|
735
|
-
|
|
736
|
-
if (touchesThisRSE) return trp;
|
|
737
|
-
if (touchesOtherRSE) return orp; // None of our endpoints intersect. Look for a general intersection between
|
|
738
|
-
// infinite lines laid over the segments
|
|
739
|
-
|
|
740
|
-
var pt = intersection(tlp, this.vector(), olp, other.vector()); // are the segments parrallel? Note that if they were colinear with overlap,
|
|
741
|
-
// they would have an endpoint intersection and that case was already handled above
|
|
742
|
-
|
|
743
|
-
if (pt === null) return null; // is the intersection found between the lines not on the segments?
|
|
744
|
-
|
|
745
|
-
if (!isInBbox(bboxOverlap, pt)) return null; // round the the computed point if needed
|
|
746
|
-
|
|
747
|
-
return rounder.round(pt.x, pt.y);
|
|
748
|
-
}
|
|
749
|
-
/**
|
|
750
|
-
* Split the given segment into multiple segments on the given points.
|
|
751
|
-
* * Each existing segment will retain its leftSE and a new rightSE will be
|
|
752
|
-
* generated for it.
|
|
753
|
-
* * A new segment will be generated which will adopt the original segment's
|
|
754
|
-
* rightSE, and a new leftSE will be generated for it.
|
|
755
|
-
* * If there are more than two points given to split on, new segments
|
|
756
|
-
* in the middle will be generated with new leftSE and rightSE's.
|
|
757
|
-
* * An array of the newly generated SweepEvents will be returned.
|
|
758
|
-
*
|
|
759
|
-
* Warning: input array of points is modified
|
|
760
|
-
*/
|
|
761
|
-
|
|
762
|
-
}, {
|
|
763
|
-
key: "split",
|
|
764
|
-
value: function split(point) {
|
|
765
|
-
var newEvents = [];
|
|
766
|
-
var alreadyLinked = point.events !== undefined;
|
|
767
|
-
var newLeftSE = new SweepEvent(point, true);
|
|
768
|
-
var newRightSE = new SweepEvent(point, false);
|
|
769
|
-
var oldRightSE = this.rightSE;
|
|
770
|
-
this.replaceRightSE(newRightSE);
|
|
771
|
-
newEvents.push(newRightSE);
|
|
772
|
-
newEvents.push(newLeftSE);
|
|
773
|
-
var newSeg = new Segment(newLeftSE, oldRightSE, this.rings.slice(), this.windings.slice()); // when splitting a nearly vertical downward-facing segment,
|
|
774
|
-
// sometimes one of the resulting new segments is vertical, in which
|
|
775
|
-
// case its left and right events may need to be swapped
|
|
776
|
-
|
|
777
|
-
if (SweepEvent.comparePoints(newSeg.leftSE.point, newSeg.rightSE.point) > 0) {
|
|
778
|
-
newSeg.swapEvents();
|
|
797
|
+
/* When a segment is split, the rightSE is replaced with a new sweep event */
|
|
798
|
+
replaceRightSE(newRightSE) {
|
|
799
|
+
this.rightSE = newRightSE;
|
|
800
|
+
this.rightSE.segment = this;
|
|
801
|
+
this.rightSE.otherSE = this.leftSE;
|
|
802
|
+
this.leftSE.otherSE = this.rightSE;
|
|
803
|
+
}
|
|
804
|
+
bbox() {
|
|
805
|
+
const y1 = this.leftSE.point.y;
|
|
806
|
+
const y2 = this.rightSE.point.y;
|
|
807
|
+
return {
|
|
808
|
+
ll: {
|
|
809
|
+
x: this.leftSE.point.x,
|
|
810
|
+
y: y1 < y2 ? y1 : y2
|
|
811
|
+
},
|
|
812
|
+
ur: {
|
|
813
|
+
x: this.rightSE.point.x,
|
|
814
|
+
y: y1 > y2 ? y1 : y2
|
|
779
815
|
}
|
|
816
|
+
};
|
|
817
|
+
}
|
|
780
818
|
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
}
|
|
819
|
+
/* A vector from the left point to the right */
|
|
820
|
+
vector() {
|
|
821
|
+
return {
|
|
822
|
+
x: this.rightSE.point.x - this.leftSE.point.x,
|
|
823
|
+
y: this.rightSE.point.y - this.leftSE.point.y
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
isAnEndpoint(pt) {
|
|
827
|
+
return pt.x === this.leftSE.point.x && pt.y === this.leftSE.point.y || pt.x === this.rightSE.point.x && pt.y === this.rightSE.point.y;
|
|
828
|
+
}
|
|
792
829
|
|
|
793
|
-
|
|
830
|
+
/* Compare this segment with a point.
|
|
831
|
+
*
|
|
832
|
+
* A point P is considered to be colinear to a segment if there
|
|
833
|
+
* exists a distance D such that if we travel along the segment
|
|
834
|
+
* from one * endpoint towards the other a distance D, we find
|
|
835
|
+
* ourselves at point P.
|
|
836
|
+
*
|
|
837
|
+
* Return value indicates:
|
|
838
|
+
*
|
|
839
|
+
* 1: point lies above the segment (to the left of vertical)
|
|
840
|
+
* 0: point is colinear to segment
|
|
841
|
+
* -1: point lies below the segment (to the right of vertical)
|
|
842
|
+
*/
|
|
843
|
+
comparePoint(point) {
|
|
844
|
+
if (this.isAnEndpoint(point)) return 0;
|
|
845
|
+
const lPt = this.leftSE.point;
|
|
846
|
+
const rPt = this.rightSE.point;
|
|
847
|
+
const v = this.vector();
|
|
848
|
+
|
|
849
|
+
// Exactly vertical segments.
|
|
850
|
+
if (lPt.x === rPt.x) {
|
|
851
|
+
if (point.x === lPt.x) return 0;
|
|
852
|
+
return point.x < lPt.x ? 1 : -1;
|
|
794
853
|
}
|
|
795
|
-
/* Swap which event is left and right */
|
|
796
854
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
855
|
+
// Nearly vertical segments with an intersection.
|
|
856
|
+
// Check to see where a point on the line with matching Y coordinate is.
|
|
857
|
+
const yDist = (point.y - lPt.y) / v.y;
|
|
858
|
+
const xFromYDist = lPt.x + yDist * v.x;
|
|
859
|
+
if (point.x === xFromYDist) return 0;
|
|
860
|
+
|
|
861
|
+
// General case.
|
|
862
|
+
// Check to see where a point on the line with matching X coordinate is.
|
|
863
|
+
const xDist = (point.x - lPt.x) / v.x;
|
|
864
|
+
const yFromXDist = lPt.y + xDist * v.y;
|
|
865
|
+
if (point.y === yFromXDist) return 0;
|
|
866
|
+
return point.y < yFromXDist ? -1 : 1;
|
|
867
|
+
}
|
|
805
868
|
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
869
|
+
/**
|
|
870
|
+
* Given another segment, returns the first non-trivial intersection
|
|
871
|
+
* between the two segments (in terms of sweep line ordering), if it exists.
|
|
872
|
+
*
|
|
873
|
+
* A 'non-trivial' intersection is one that will cause one or both of the
|
|
874
|
+
* segments to be split(). As such, 'trivial' vs. 'non-trivial' intersection:
|
|
875
|
+
*
|
|
876
|
+
* * endpoint of segA with endpoint of segB --> trivial
|
|
877
|
+
* * endpoint of segA with point along segB --> non-trivial
|
|
878
|
+
* * endpoint of segB with point along segA --> non-trivial
|
|
879
|
+
* * point along segA with point along segB --> non-trivial
|
|
880
|
+
*
|
|
881
|
+
* If no non-trivial intersection exists, return null
|
|
882
|
+
* Else, return null.
|
|
883
|
+
*/
|
|
884
|
+
getIntersection(other) {
|
|
885
|
+
// If bboxes don't overlap, there can't be any intersections
|
|
886
|
+
const tBbox = this.bbox();
|
|
887
|
+
const oBbox = other.bbox();
|
|
888
|
+
const bboxOverlap = getBboxOverlap(tBbox, oBbox);
|
|
889
|
+
if (bboxOverlap === null) return null;
|
|
890
|
+
|
|
891
|
+
// We first check to see if the endpoints can be considered intersections.
|
|
892
|
+
// This will 'snap' intersections to endpoints if possible, and will
|
|
893
|
+
// handle cases of colinearity.
|
|
894
|
+
|
|
895
|
+
const tlp = this.leftSE.point;
|
|
896
|
+
const trp = this.rightSE.point;
|
|
897
|
+
const olp = other.leftSE.point;
|
|
898
|
+
const orp = other.rightSE.point;
|
|
899
|
+
|
|
900
|
+
// does each endpoint touch the other segment?
|
|
901
|
+
// note that we restrict the 'touching' definition to only allow segments
|
|
902
|
+
// to touch endpoints that lie forward from where we are in the sweep line pass
|
|
903
|
+
const touchesOtherLSE = isInBbox(tBbox, olp) && this.comparePoint(olp) === 0;
|
|
904
|
+
const touchesThisLSE = isInBbox(oBbox, tlp) && other.comparePoint(tlp) === 0;
|
|
905
|
+
const touchesOtherRSE = isInBbox(tBbox, orp) && this.comparePoint(orp) === 0;
|
|
906
|
+
const touchesThisRSE = isInBbox(oBbox, trp) && other.comparePoint(trp) === 0;
|
|
907
|
+
|
|
908
|
+
// do left endpoints match?
|
|
909
|
+
if (touchesThisLSE && touchesOtherLSE) {
|
|
910
|
+
// these two cases are for colinear segments with matching left
|
|
911
|
+
// endpoints, and one segment being longer than the other
|
|
912
|
+
if (touchesThisRSE && !touchesOtherRSE) return trp;
|
|
913
|
+
if (!touchesThisRSE && touchesOtherRSE) return orp;
|
|
914
|
+
// either the two segments match exactly (two trival intersections)
|
|
915
|
+
// or just on their left endpoint (one trivial intersection
|
|
916
|
+
return null;
|
|
809
917
|
}
|
|
810
|
-
/* Consume another segment. We take their rings under our wing
|
|
811
|
-
* and mark them as consumed. Use for perfectly overlapping segments */
|
|
812
|
-
|
|
813
|
-
}, {
|
|
814
|
-
key: "consume",
|
|
815
|
-
value: function consume(other) {
|
|
816
|
-
var consumer = this;
|
|
817
|
-
var consumee = other;
|
|
818
918
|
|
|
819
|
-
|
|
820
|
-
|
|
919
|
+
// does this left endpoint matches (other doesn't)
|
|
920
|
+
if (touchesThisLSE) {
|
|
921
|
+
// check for segments that just intersect on opposing endpoints
|
|
922
|
+
if (touchesOtherRSE) {
|
|
923
|
+
if (tlp.x === orp.x && tlp.y === orp.y) return null;
|
|
821
924
|
}
|
|
925
|
+
// t-intersection on left endpoint
|
|
926
|
+
return tlp;
|
|
927
|
+
}
|
|
822
928
|
|
|
823
|
-
|
|
824
|
-
|
|
929
|
+
// does other left endpoint matches (this doesn't)
|
|
930
|
+
if (touchesOtherLSE) {
|
|
931
|
+
// check for segments that just intersect on opposing endpoints
|
|
932
|
+
if (touchesThisRSE) {
|
|
933
|
+
if (trp.x === olp.x && trp.y === olp.y) return null;
|
|
825
934
|
}
|
|
935
|
+
// t-intersection on left endpoint
|
|
936
|
+
return olp;
|
|
937
|
+
}
|
|
826
938
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
// the winner of the consumption is the earlier segment
|
|
830
|
-
// according to sweep line ordering
|
|
831
|
-
|
|
832
|
-
if (cmp > 0) {
|
|
833
|
-
var tmp = consumer;
|
|
834
|
-
consumer = consumee;
|
|
835
|
-
consumee = tmp;
|
|
836
|
-
} // make sure a segment doesn't consume it's prev
|
|
837
|
-
|
|
939
|
+
// trivial intersection on right endpoints
|
|
940
|
+
if (touchesThisRSE && touchesOtherRSE) return null;
|
|
838
941
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
consumee = _tmp;
|
|
843
|
-
}
|
|
942
|
+
// t-intersections on just one right endpoint
|
|
943
|
+
if (touchesThisRSE) return trp;
|
|
944
|
+
if (touchesOtherRSE) return orp;
|
|
844
945
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
var index = consumer.rings.indexOf(ring);
|
|
946
|
+
// None of our endpoints intersect. Look for a general intersection between
|
|
947
|
+
// infinite lines laid over the segments
|
|
948
|
+
const pt = intersection$1(tlp, this.vector(), olp, other.vector());
|
|
849
949
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
} else consumer.windings[index] += winding;
|
|
854
|
-
}
|
|
950
|
+
// are the segments parrallel? Note that if they were colinear with overlap,
|
|
951
|
+
// they would have an endpoint intersection and that case was already handled above
|
|
952
|
+
if (pt === null) return null;
|
|
855
953
|
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
consumee.consumedBy = consumer; // mark sweep events consumed as to maintain ordering in sweep event queue
|
|
859
|
-
|
|
860
|
-
consumee.leftSE.consumedBy = consumer.leftSE;
|
|
861
|
-
consumee.rightSE.consumedBy = consumer.rightSE;
|
|
862
|
-
}
|
|
863
|
-
/* The first segment previous segment chain that is in the result */
|
|
864
|
-
|
|
865
|
-
}, {
|
|
866
|
-
key: "prevInResult",
|
|
867
|
-
value: function prevInResult() {
|
|
868
|
-
if (this._prevInResult !== undefined) return this._prevInResult;
|
|
869
|
-
if (!this.prev) this._prevInResult = null;else if (this.prev.isInResult()) this._prevInResult = this.prev;else this._prevInResult = this.prev.prevInResult();
|
|
870
|
-
return this._prevInResult;
|
|
871
|
-
}
|
|
872
|
-
}, {
|
|
873
|
-
key: "beforeState",
|
|
874
|
-
value: function beforeState() {
|
|
875
|
-
if (this._beforeState !== undefined) return this._beforeState;
|
|
876
|
-
if (!this.prev) this._beforeState = {
|
|
877
|
-
rings: [],
|
|
878
|
-
windings: [],
|
|
879
|
-
multiPolys: []
|
|
880
|
-
};else {
|
|
881
|
-
var seg = this.prev.consumedBy || this.prev;
|
|
882
|
-
this._beforeState = seg.afterState();
|
|
883
|
-
}
|
|
884
|
-
return this._beforeState;
|
|
885
|
-
}
|
|
886
|
-
}, {
|
|
887
|
-
key: "afterState",
|
|
888
|
-
value: function afterState() {
|
|
889
|
-
if (this._afterState !== undefined) return this._afterState;
|
|
890
|
-
var beforeState = this.beforeState();
|
|
891
|
-
this._afterState = {
|
|
892
|
-
rings: beforeState.rings.slice(0),
|
|
893
|
-
windings: beforeState.windings.slice(0),
|
|
894
|
-
multiPolys: []
|
|
895
|
-
};
|
|
896
|
-
var ringsAfter = this._afterState.rings;
|
|
897
|
-
var windingsAfter = this._afterState.windings;
|
|
898
|
-
var mpsAfter = this._afterState.multiPolys; // calculate ringsAfter, windingsAfter
|
|
899
|
-
|
|
900
|
-
for (var i = 0, iMax = this.rings.length; i < iMax; i++) {
|
|
901
|
-
var ring = this.rings[i];
|
|
902
|
-
var winding = this.windings[i];
|
|
903
|
-
var index = ringsAfter.indexOf(ring);
|
|
904
|
-
|
|
905
|
-
if (index === -1) {
|
|
906
|
-
ringsAfter.push(ring);
|
|
907
|
-
windingsAfter.push(winding);
|
|
908
|
-
} else windingsAfter[index] += winding;
|
|
909
|
-
} // calcualte polysAfter
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
var polysAfter = [];
|
|
913
|
-
var polysExclude = [];
|
|
914
|
-
|
|
915
|
-
for (var _i = 0, _iMax = ringsAfter.length; _i < _iMax; _i++) {
|
|
916
|
-
if (windingsAfter[_i] === 0) continue; // non-zero rule
|
|
917
|
-
|
|
918
|
-
var _ring = ringsAfter[_i];
|
|
919
|
-
var poly = _ring.poly;
|
|
920
|
-
if (polysExclude.indexOf(poly) !== -1) continue;
|
|
921
|
-
if (_ring.isExterior) polysAfter.push(poly);else {
|
|
922
|
-
if (polysExclude.indexOf(poly) === -1) polysExclude.push(poly);
|
|
923
|
-
|
|
924
|
-
var _index = polysAfter.indexOf(_ring.poly);
|
|
925
|
-
|
|
926
|
-
if (_index !== -1) polysAfter.splice(_index, 1);
|
|
927
|
-
}
|
|
928
|
-
} // calculate multiPolysAfter
|
|
954
|
+
// is the intersection found between the lines not on the segments?
|
|
955
|
+
if (!isInBbox(bboxOverlap, pt)) return null;
|
|
929
956
|
|
|
957
|
+
// round the the computed point if needed
|
|
958
|
+
return rounder.round(pt.x, pt.y);
|
|
959
|
+
}
|
|
930
960
|
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
961
|
+
/**
|
|
962
|
+
* Split the given segment into multiple segments on the given points.
|
|
963
|
+
* * Each existing segment will retain its leftSE and a new rightSE will be
|
|
964
|
+
* generated for it.
|
|
965
|
+
* * A new segment will be generated which will adopt the original segment's
|
|
966
|
+
* rightSE, and a new leftSE will be generated for it.
|
|
967
|
+
* * If there are more than two points given to split on, new segments
|
|
968
|
+
* in the middle will be generated with new leftSE and rightSE's.
|
|
969
|
+
* * An array of the newly generated SweepEvents will be returned.
|
|
970
|
+
*
|
|
971
|
+
* Warning: input array of points is modified
|
|
972
|
+
*/
|
|
973
|
+
split(point) {
|
|
974
|
+
const newEvents = [];
|
|
975
|
+
const alreadyLinked = point.events !== undefined;
|
|
976
|
+
const newLeftSE = new SweepEvent(point, true);
|
|
977
|
+
const newRightSE = new SweepEvent(point, false);
|
|
978
|
+
const oldRightSE = this.rightSE;
|
|
979
|
+
this.replaceRightSE(newRightSE);
|
|
980
|
+
newEvents.push(newRightSE);
|
|
981
|
+
newEvents.push(newLeftSE);
|
|
982
|
+
const newSeg = new Segment(newLeftSE, oldRightSE, this.rings.slice(), this.windings.slice());
|
|
983
|
+
|
|
984
|
+
// when splitting a nearly vertical downward-facing segment,
|
|
985
|
+
// sometimes one of the resulting new segments is vertical, in which
|
|
986
|
+
// case its left and right events may need to be swapped
|
|
987
|
+
if (SweepEvent.comparePoints(newSeg.leftSE.point, newSeg.rightSE.point) > 0) {
|
|
988
|
+
newSeg.swapEvents();
|
|
989
|
+
}
|
|
990
|
+
if (SweepEvent.comparePoints(this.leftSE.point, this.rightSE.point) > 0) {
|
|
991
|
+
this.swapEvents();
|
|
992
|
+
}
|
|
935
993
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
if (this._isInResult !== undefined) return this._isInResult;
|
|
946
|
-
var mpsBefore = this.beforeState().multiPolys;
|
|
947
|
-
var mpsAfter = this.afterState().multiPolys;
|
|
948
|
-
|
|
949
|
-
switch (operation.type) {
|
|
950
|
-
case 'union':
|
|
951
|
-
{
|
|
952
|
-
// UNION - included iff:
|
|
953
|
-
// * On one side of us there is 0 poly interiors AND
|
|
954
|
-
// * On the other side there is 1 or more.
|
|
955
|
-
var noBefores = mpsBefore.length === 0;
|
|
956
|
-
var noAfters = mpsAfter.length === 0;
|
|
957
|
-
this._isInResult = noBefores !== noAfters;
|
|
958
|
-
break;
|
|
959
|
-
}
|
|
994
|
+
// in the point we just used to create new sweep events with was already
|
|
995
|
+
// linked to other events, we need to check if either of the affected
|
|
996
|
+
// segments should be consumed
|
|
997
|
+
if (alreadyLinked) {
|
|
998
|
+
newLeftSE.checkForConsuming();
|
|
999
|
+
newRightSE.checkForConsuming();
|
|
1000
|
+
}
|
|
1001
|
+
return newEvents;
|
|
1002
|
+
}
|
|
960
1003
|
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
most = mpsAfter.length;
|
|
973
|
-
} else {
|
|
974
|
-
least = mpsAfter.length;
|
|
975
|
-
most = mpsBefore.length;
|
|
976
|
-
}
|
|
1004
|
+
/* Swap which event is left and right */
|
|
1005
|
+
swapEvents() {
|
|
1006
|
+
const tmpEvt = this.rightSE;
|
|
1007
|
+
this.rightSE = this.leftSE;
|
|
1008
|
+
this.leftSE = tmpEvt;
|
|
1009
|
+
this.leftSE.isLeft = true;
|
|
1010
|
+
this.rightSE.isLeft = false;
|
|
1011
|
+
for (let i = 0, iMax = this.windings.length; i < iMax; i++) {
|
|
1012
|
+
this.windings[i] *= -1;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
977
1015
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1016
|
+
/* Consume another segment. We take their rings under our wing
|
|
1017
|
+
* and mark them as consumed. Use for perfectly overlapping segments */
|
|
1018
|
+
consume(other) {
|
|
1019
|
+
let consumer = this;
|
|
1020
|
+
let consumee = other;
|
|
1021
|
+
while (consumer.consumedBy) consumer = consumer.consumedBy;
|
|
1022
|
+
while (consumee.consumedBy) consumee = consumee.consumedBy;
|
|
1023
|
+
const cmp = Segment.compare(consumer, consumee);
|
|
1024
|
+
if (cmp === 0) return; // already consumed
|
|
1025
|
+
// the winner of the consumption is the earlier segment
|
|
1026
|
+
// according to sweep line ordering
|
|
1027
|
+
if (cmp > 0) {
|
|
1028
|
+
const tmp = consumer;
|
|
1029
|
+
consumer = consumee;
|
|
1030
|
+
consumee = tmp;
|
|
1031
|
+
}
|
|
981
1032
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1033
|
+
// make sure a segment doesn't consume it's prev
|
|
1034
|
+
if (consumer.prev === consumee) {
|
|
1035
|
+
const tmp = consumer;
|
|
1036
|
+
consumer = consumee;
|
|
1037
|
+
consumee = tmp;
|
|
1038
|
+
}
|
|
1039
|
+
for (let i = 0, iMax = consumee.rings.length; i < iMax; i++) {
|
|
1040
|
+
const ring = consumee.rings[i];
|
|
1041
|
+
const winding = consumee.windings[i];
|
|
1042
|
+
const index = consumer.rings.indexOf(ring);
|
|
1043
|
+
if (index === -1) {
|
|
1044
|
+
consumer.rings.push(ring);
|
|
1045
|
+
consumer.windings.push(winding);
|
|
1046
|
+
} else consumer.windings[index] += winding;
|
|
1047
|
+
}
|
|
1048
|
+
consumee.rings = null;
|
|
1049
|
+
consumee.windings = null;
|
|
1050
|
+
consumee.consumedBy = consumer;
|
|
991
1051
|
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
var isJustSubject = function isJustSubject(mps) {
|
|
997
|
-
return mps.length === 1 && mps[0].isSubject;
|
|
998
|
-
};
|
|
1052
|
+
// mark sweep events consumed as to maintain ordering in sweep event queue
|
|
1053
|
+
consumee.leftSE.consumedBy = consumer.leftSE;
|
|
1054
|
+
consumee.rightSE.consumedBy = consumer.rightSE;
|
|
1055
|
+
}
|
|
999
1056
|
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1057
|
+
/* The first segment previous segment chain that is in the result */
|
|
1058
|
+
prevInResult() {
|
|
1059
|
+
if (this._prevInResult !== undefined) return this._prevInResult;
|
|
1060
|
+
if (!this.prev) this._prevInResult = null;else if (this.prev.isInResult()) this._prevInResult = this.prev;else this._prevInResult = this.prev.prevInResult();
|
|
1061
|
+
return this._prevInResult;
|
|
1062
|
+
}
|
|
1063
|
+
beforeState() {
|
|
1064
|
+
if (this._beforeState !== undefined) return this._beforeState;
|
|
1065
|
+
if (!this.prev) this._beforeState = {
|
|
1066
|
+
rings: [],
|
|
1067
|
+
windings: [],
|
|
1068
|
+
multiPolys: []
|
|
1069
|
+
};else {
|
|
1070
|
+
const seg = this.prev.consumedBy || this.prev;
|
|
1071
|
+
this._beforeState = seg.afterState();
|
|
1072
|
+
}
|
|
1073
|
+
return this._beforeState;
|
|
1074
|
+
}
|
|
1075
|
+
afterState() {
|
|
1076
|
+
if (this._afterState !== undefined) return this._afterState;
|
|
1077
|
+
const beforeState = this.beforeState();
|
|
1078
|
+
this._afterState = {
|
|
1079
|
+
rings: beforeState.rings.slice(0),
|
|
1080
|
+
windings: beforeState.windings.slice(0),
|
|
1081
|
+
multiPolys: []
|
|
1082
|
+
};
|
|
1083
|
+
const ringsAfter = this._afterState.rings;
|
|
1084
|
+
const windingsAfter = this._afterState.windings;
|
|
1085
|
+
const mpsAfter = this._afterState.multiPolys;
|
|
1086
|
+
|
|
1087
|
+
// calculate ringsAfter, windingsAfter
|
|
1088
|
+
for (let i = 0, iMax = this.rings.length; i < iMax; i++) {
|
|
1089
|
+
const ring = this.rings[i];
|
|
1090
|
+
const winding = this.windings[i];
|
|
1091
|
+
const index = ringsAfter.indexOf(ring);
|
|
1092
|
+
if (index === -1) {
|
|
1093
|
+
ringsAfter.push(ring);
|
|
1094
|
+
windingsAfter.push(winding);
|
|
1095
|
+
} else windingsAfter[index] += winding;
|
|
1096
|
+
}
|
|
1003
1097
|
|
|
1004
|
-
|
|
1005
|
-
|
|
1098
|
+
// calcualte polysAfter
|
|
1099
|
+
const polysAfter = [];
|
|
1100
|
+
const polysExclude = [];
|
|
1101
|
+
for (let i = 0, iMax = ringsAfter.length; i < iMax; i++) {
|
|
1102
|
+
if (windingsAfter[i] === 0) continue; // non-zero rule
|
|
1103
|
+
const ring = ringsAfter[i];
|
|
1104
|
+
const poly = ring.poly;
|
|
1105
|
+
if (polysExclude.indexOf(poly) !== -1) continue;
|
|
1106
|
+
if (ring.isExterior) polysAfter.push(poly);else {
|
|
1107
|
+
if (polysExclude.indexOf(poly) === -1) polysExclude.push(poly);
|
|
1108
|
+
const index = polysAfter.indexOf(ring.poly);
|
|
1109
|
+
if (index !== -1) polysAfter.splice(index, 1);
|
|
1006
1110
|
}
|
|
1007
|
-
|
|
1008
|
-
return this._isInResult;
|
|
1009
1111
|
}
|
|
1010
|
-
}], [{
|
|
1011
|
-
key: "fromRing",
|
|
1012
|
-
value: function fromRing(pt1, pt2, ring) {
|
|
1013
|
-
var leftPt, rightPt, winding; // ordering the two points according to sweep line ordering
|
|
1014
1112
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
rightPt = pt2;
|
|
1020
|
-
winding = 1;
|
|
1021
|
-
} else if (cmpPts > 0) {
|
|
1022
|
-
leftPt = pt2;
|
|
1023
|
-
rightPt = pt1;
|
|
1024
|
-
winding = -1;
|
|
1025
|
-
} else throw new Error("Tried to create degenerate segment at [".concat(pt1.x, ", ").concat(pt1.y, "]"));
|
|
1026
|
-
|
|
1027
|
-
var leftSE = new SweepEvent(leftPt, true);
|
|
1028
|
-
var rightSE = new SweepEvent(rightPt, false);
|
|
1029
|
-
return new Segment(leftSE, rightSE, [ring], [winding]);
|
|
1113
|
+
// calculate multiPolysAfter
|
|
1114
|
+
for (let i = 0, iMax = polysAfter.length; i < iMax; i++) {
|
|
1115
|
+
const mp = polysAfter[i].multiPoly;
|
|
1116
|
+
if (mpsAfter.indexOf(mp) === -1) mpsAfter.push(mp);
|
|
1030
1117
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
return Segment;
|
|
1034
|
-
}();
|
|
1118
|
+
return this._afterState;
|
|
1119
|
+
}
|
|
1035
1120
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1121
|
+
/* Is this segment part of the final result? */
|
|
1122
|
+
isInResult() {
|
|
1123
|
+
// if we've been consumed, we're not in the result
|
|
1124
|
+
if (this.consumedBy) return false;
|
|
1125
|
+
if (this._isInResult !== undefined) return this._isInResult;
|
|
1126
|
+
const mpsBefore = this.beforeState().multiPolys;
|
|
1127
|
+
const mpsAfter = this.afterState().multiPolys;
|
|
1128
|
+
switch (operation.type) {
|
|
1129
|
+
case "union":
|
|
1130
|
+
{
|
|
1131
|
+
// UNION - included iff:
|
|
1132
|
+
// * On one side of us there is 0 poly interiors AND
|
|
1133
|
+
// * On the other side there is 1 or more.
|
|
1134
|
+
const noBefores = mpsBefore.length === 0;
|
|
1135
|
+
const noAfters = mpsAfter.length === 0;
|
|
1136
|
+
this._isInResult = noBefores !== noAfters;
|
|
1137
|
+
break;
|
|
1138
|
+
}
|
|
1139
|
+
case "intersection":
|
|
1140
|
+
{
|
|
1141
|
+
// INTERSECTION - included iff:
|
|
1142
|
+
// * on one side of us all multipolys are rep. with poly interiors AND
|
|
1143
|
+
// * on the other side of us, not all multipolys are repsented
|
|
1144
|
+
// with poly interiors
|
|
1145
|
+
let least;
|
|
1146
|
+
let most;
|
|
1147
|
+
if (mpsBefore.length < mpsAfter.length) {
|
|
1148
|
+
least = mpsBefore.length;
|
|
1149
|
+
most = mpsAfter.length;
|
|
1150
|
+
} else {
|
|
1151
|
+
least = mpsAfter.length;
|
|
1152
|
+
most = mpsBefore.length;
|
|
1153
|
+
}
|
|
1154
|
+
this._isInResult = most === operation.numMultiPolys && least < most;
|
|
1155
|
+
break;
|
|
1156
|
+
}
|
|
1157
|
+
case "xor":
|
|
1158
|
+
{
|
|
1159
|
+
// XOR - included iff:
|
|
1160
|
+
// * the difference between the number of multipolys represented
|
|
1161
|
+
// with poly interiors on our two sides is an odd number
|
|
1162
|
+
const diff = Math.abs(mpsBefore.length - mpsAfter.length);
|
|
1163
|
+
this._isInResult = diff % 2 === 1;
|
|
1164
|
+
break;
|
|
1165
|
+
}
|
|
1166
|
+
case "difference":
|
|
1167
|
+
{
|
|
1168
|
+
// DIFFERENCE included iff:
|
|
1169
|
+
// * on exactly one side, we have just the subject
|
|
1170
|
+
const isJustSubject = mps => mps.length === 1 && mps[0].isSubject;
|
|
1171
|
+
this._isInResult = isJustSubject(mpsBefore) !== isJustSubject(mpsAfter);
|
|
1172
|
+
break;
|
|
1173
|
+
}
|
|
1174
|
+
default:
|
|
1175
|
+
throw new Error(`Unrecognized operation type found ${operation.type}`);
|
|
1176
|
+
}
|
|
1177
|
+
return this._isInResult;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1039
1180
|
|
|
1181
|
+
class RingIn {
|
|
1182
|
+
constructor(geomRing, poly, isExterior) {
|
|
1040
1183
|
if (!Array.isArray(geomRing) || geomRing.length === 0) {
|
|
1041
|
-
throw new Error(
|
|
1184
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
1042
1185
|
}
|
|
1043
|
-
|
|
1044
1186
|
this.poly = poly;
|
|
1045
1187
|
this.isExterior = isExterior;
|
|
1046
1188
|
this.segments = [];
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
throw new Error('Input geometry is not a valid Polygon or MultiPolygon');
|
|
1189
|
+
if (typeof geomRing[0][0] !== "number" || typeof geomRing[0][1] !== "number") {
|
|
1190
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
1050
1191
|
}
|
|
1051
|
-
|
|
1052
|
-
var firstPoint = rounder.round(geomRing[0][0], geomRing[0][1]);
|
|
1192
|
+
const firstPoint = rounder.round(geomRing[0][0], geomRing[0][1]);
|
|
1053
1193
|
this.bbox = {
|
|
1054
1194
|
ll: {
|
|
1055
1195
|
x: firstPoint.x,
|
|
@@ -1060,15 +1200,13 @@ var RingIn = /*#__PURE__*/function () {
|
|
|
1060
1200
|
y: firstPoint.y
|
|
1061
1201
|
}
|
|
1062
1202
|
};
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
throw new Error('Input geometry is not a valid Polygon or MultiPolygon');
|
|
1203
|
+
let prevPoint = firstPoint;
|
|
1204
|
+
for (let i = 1, iMax = geomRing.length; i < iMax; i++) {
|
|
1205
|
+
if (typeof geomRing[i][0] !== "number" || typeof geomRing[i][1] !== "number") {
|
|
1206
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
1068
1207
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1208
|
+
let point = rounder.round(geomRing[i][0], geomRing[i][1]);
|
|
1209
|
+
// skip repeated points
|
|
1072
1210
|
if (point.x === prevPoint.x && point.y === prevPoint.y) continue;
|
|
1073
1211
|
this.segments.push(Segment.fromRing(prevPoint, point, this));
|
|
1074
1212
|
if (point.x < this.bbox.ll.x) this.bbox.ll.x = point.x;
|
|
@@ -1076,41 +1214,29 @@ var RingIn = /*#__PURE__*/function () {
|
|
|
1076
1214
|
if (point.x > this.bbox.ur.x) this.bbox.ur.x = point.x;
|
|
1077
1215
|
if (point.y > this.bbox.ur.y) this.bbox.ur.y = point.y;
|
|
1078
1216
|
prevPoint = point;
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1217
|
+
}
|
|
1218
|
+
// add segment from last to first if last is not the same as first
|
|
1082
1219
|
if (firstPoint.x !== prevPoint.x || firstPoint.y !== prevPoint.y) {
|
|
1083
1220
|
this.segments.push(Segment.fromRing(prevPoint, firstPoint, this));
|
|
1084
1221
|
}
|
|
1085
1222
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
for (var i = 0, iMax = this.segments.length; i < iMax; i++) {
|
|
1093
|
-
var segment = this.segments[i];
|
|
1094
|
-
sweepEvents.push(segment.leftSE);
|
|
1095
|
-
sweepEvents.push(segment.rightSE);
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
return sweepEvents;
|
|
1223
|
+
getSweepEvents() {
|
|
1224
|
+
const sweepEvents = [];
|
|
1225
|
+
for (let i = 0, iMax = this.segments.length; i < iMax; i++) {
|
|
1226
|
+
const segment = this.segments[i];
|
|
1227
|
+
sweepEvents.push(segment.leftSE);
|
|
1228
|
+
sweepEvents.push(segment.rightSE);
|
|
1099
1229
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
function PolyIn(geomPoly, multiPoly) {
|
|
1106
|
-
_classCallCheck(this, PolyIn);
|
|
1107
|
-
|
|
1230
|
+
return sweepEvents;
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
class PolyIn {
|
|
1234
|
+
constructor(geomPoly, multiPoly) {
|
|
1108
1235
|
if (!Array.isArray(geomPoly)) {
|
|
1109
|
-
throw new Error(
|
|
1236
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
1110
1237
|
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1238
|
+
this.exteriorRing = new RingIn(geomPoly[0], this, true);
|
|
1239
|
+
// copy by value
|
|
1114
1240
|
this.bbox = {
|
|
1115
1241
|
ll: {
|
|
1116
1242
|
x: this.exteriorRing.bbox.ll.x,
|
|
@@ -1122,53 +1248,39 @@ var PolyIn = /*#__PURE__*/function () {
|
|
|
1122
1248
|
}
|
|
1123
1249
|
};
|
|
1124
1250
|
this.interiorRings = [];
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
var ring = new RingIn(geomPoly[i], this, false);
|
|
1251
|
+
for (let i = 1, iMax = geomPoly.length; i < iMax; i++) {
|
|
1252
|
+
const ring = new RingIn(geomPoly[i], this, false);
|
|
1128
1253
|
if (ring.bbox.ll.x < this.bbox.ll.x) this.bbox.ll.x = ring.bbox.ll.x;
|
|
1129
1254
|
if (ring.bbox.ll.y < this.bbox.ll.y) this.bbox.ll.y = ring.bbox.ll.y;
|
|
1130
1255
|
if (ring.bbox.ur.x > this.bbox.ur.x) this.bbox.ur.x = ring.bbox.ur.x;
|
|
1131
1256
|
if (ring.bbox.ur.y > this.bbox.ur.y) this.bbox.ur.y = ring.bbox.ur.y;
|
|
1132
1257
|
this.interiorRings.push(ring);
|
|
1133
1258
|
}
|
|
1134
|
-
|
|
1135
1259
|
this.multiPoly = multiPoly;
|
|
1136
1260
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
for (var i = 0, iMax = this.interiorRings.length; i < iMax; i++) {
|
|
1144
|
-
var ringSweepEvents = this.interiorRings[i].getSweepEvents();
|
|
1145
|
-
|
|
1146
|
-
for (var j = 0, jMax = ringSweepEvents.length; j < jMax; j++) {
|
|
1147
|
-
sweepEvents.push(ringSweepEvents[j]);
|
|
1148
|
-
}
|
|
1261
|
+
getSweepEvents() {
|
|
1262
|
+
const sweepEvents = this.exteriorRing.getSweepEvents();
|
|
1263
|
+
for (let i = 0, iMax = this.interiorRings.length; i < iMax; i++) {
|
|
1264
|
+
const ringSweepEvents = this.interiorRings[i].getSweepEvents();
|
|
1265
|
+
for (let j = 0, jMax = ringSweepEvents.length; j < jMax; j++) {
|
|
1266
|
+
sweepEvents.push(ringSweepEvents[j]);
|
|
1149
1267
|
}
|
|
1150
|
-
|
|
1151
|
-
return sweepEvents;
|
|
1152
1268
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
function MultiPolyIn(geom, isSubject) {
|
|
1159
|
-
_classCallCheck(this, MultiPolyIn);
|
|
1160
|
-
|
|
1269
|
+
return sweepEvents;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
class MultiPolyIn {
|
|
1273
|
+
constructor(geom, isSubject) {
|
|
1161
1274
|
if (!Array.isArray(geom)) {
|
|
1162
|
-
throw new Error(
|
|
1275
|
+
throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
|
|
1163
1276
|
}
|
|
1164
|
-
|
|
1165
1277
|
try {
|
|
1166
1278
|
// if the input looks like a polygon, convert it to a multipolygon
|
|
1167
|
-
if (typeof geom[0][0][0] ===
|
|
1168
|
-
} catch (ex) {
|
|
1279
|
+
if (typeof geom[0][0][0] === "number") geom = [geom];
|
|
1280
|
+
} catch (ex) {
|
|
1281
|
+
// The input is either malformed or has empty arrays.
|
|
1169
1282
|
// In either case, it will be handled later on.
|
|
1170
1283
|
}
|
|
1171
|
-
|
|
1172
1284
|
this.polys = [];
|
|
1173
1285
|
this.bbox = {
|
|
1174
1286
|
ll: {
|
|
@@ -1180,311 +1292,234 @@ var MultiPolyIn = /*#__PURE__*/function () {
|
|
|
1180
1292
|
y: Number.NEGATIVE_INFINITY
|
|
1181
1293
|
}
|
|
1182
1294
|
};
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
var poly = new PolyIn(geom[i], this);
|
|
1295
|
+
for (let i = 0, iMax = geom.length; i < iMax; i++) {
|
|
1296
|
+
const poly = new PolyIn(geom[i], this);
|
|
1186
1297
|
if (poly.bbox.ll.x < this.bbox.ll.x) this.bbox.ll.x = poly.bbox.ll.x;
|
|
1187
1298
|
if (poly.bbox.ll.y < this.bbox.ll.y) this.bbox.ll.y = poly.bbox.ll.y;
|
|
1188
1299
|
if (poly.bbox.ur.x > this.bbox.ur.x) this.bbox.ur.x = poly.bbox.ur.x;
|
|
1189
1300
|
if (poly.bbox.ur.y > this.bbox.ur.y) this.bbox.ur.y = poly.bbox.ur.y;
|
|
1190
1301
|
this.polys.push(poly);
|
|
1191
1302
|
}
|
|
1192
|
-
|
|
1193
1303
|
this.isSubject = isSubject;
|
|
1194
1304
|
}
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
for (var i = 0, iMax = this.polys.length; i < iMax; i++) {
|
|
1202
|
-
var polySweepEvents = this.polys[i].getSweepEvents();
|
|
1203
|
-
|
|
1204
|
-
for (var j = 0, jMax = polySweepEvents.length; j < jMax; j++) {
|
|
1205
|
-
sweepEvents.push(polySweepEvents[j]);
|
|
1206
|
-
}
|
|
1305
|
+
getSweepEvents() {
|
|
1306
|
+
const sweepEvents = [];
|
|
1307
|
+
for (let i = 0, iMax = this.polys.length; i < iMax; i++) {
|
|
1308
|
+
const polySweepEvents = this.polys[i].getSweepEvents();
|
|
1309
|
+
for (let j = 0, jMax = polySweepEvents.length; j < jMax; j++) {
|
|
1310
|
+
sweepEvents.push(polySweepEvents[j]);
|
|
1207
1311
|
}
|
|
1208
|
-
|
|
1209
|
-
return sweepEvents;
|
|
1210
1312
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
}();
|
|
1215
|
-
|
|
1216
|
-
var RingOut = /*#__PURE__*/function () {
|
|
1217
|
-
_createClass(RingOut, null, [{
|
|
1218
|
-
key: "factory",
|
|
1219
|
-
|
|
1220
|
-
/* Given the segments from the sweep line pass, compute & return a series
|
|
1221
|
-
* of closed rings from all the segments marked to be part of the result */
|
|
1222
|
-
value: function factory(allSegments) {
|
|
1223
|
-
var ringsOut = [];
|
|
1313
|
+
return sweepEvents;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1224
1316
|
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1317
|
+
class RingOut {
|
|
1318
|
+
/* Given the segments from the sweep line pass, compute & return a series
|
|
1319
|
+
* of closed rings from all the segments marked to be part of the result */
|
|
1320
|
+
static factory(allSegments) {
|
|
1321
|
+
const ringsOut = [];
|
|
1322
|
+
for (let i = 0, iMax = allSegments.length; i < iMax; i++) {
|
|
1323
|
+
const segment = allSegments[i];
|
|
1324
|
+
if (!segment.isInResult() || segment.ringOut) continue;
|
|
1325
|
+
let prevEvent = null;
|
|
1326
|
+
let event = segment.leftSE;
|
|
1327
|
+
let nextEvent = segment.rightSE;
|
|
1328
|
+
const events = [event];
|
|
1329
|
+
const startingPoint = event.point;
|
|
1330
|
+
const intersectionLEs = [];
|
|
1331
|
+
|
|
1332
|
+
/* Walk the chain of linked events to form a closed ring */
|
|
1333
|
+
while (true) {
|
|
1334
|
+
prevEvent = event;
|
|
1335
|
+
event = nextEvent;
|
|
1336
|
+
events.push(event);
|
|
1235
1337
|
|
|
1338
|
+
/* Is the ring complete? */
|
|
1339
|
+
if (event.point === startingPoint) break;
|
|
1236
1340
|
while (true) {
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
/* Did we hit a dead end? This shouldn't happen. Indicates some earlier
|
|
1247
|
-
* part of the algorithm malfunctioned... please file a bug report. */
|
|
1248
|
-
|
|
1249
|
-
if (availableLEs.length === 0) {
|
|
1250
|
-
var firstPt = events[0].point;
|
|
1251
|
-
var lastPt = events[events.length - 1].point;
|
|
1252
|
-
throw new Error("Unable to complete output ring starting at [".concat(firstPt.x, ",") + " ".concat(firstPt.y, "]. Last matching segment found ends at") + " [".concat(lastPt.x, ", ").concat(lastPt.y, "]."));
|
|
1253
|
-
}
|
|
1254
|
-
/* Only one way to go, so cotinue on the path */
|
|
1341
|
+
const availableLEs = event.getAvailableLinkedEvents();
|
|
1342
|
+
|
|
1343
|
+
/* Did we hit a dead end? This shouldn't happen.
|
|
1344
|
+
* Indicates some earlier part of the algorithm malfunctioned. */
|
|
1345
|
+
if (availableLEs.length === 0) {
|
|
1346
|
+
const firstPt = events[0].point;
|
|
1347
|
+
const lastPt = events[events.length - 1].point;
|
|
1348
|
+
throw new Error(`Unable to complete output ring starting at [${firstPt.x},` + ` ${firstPt.y}]. Last matching segment found ends at` + ` [${lastPt.x}, ${lastPt.y}].`);
|
|
1349
|
+
}
|
|
1255
1350
|
|
|
1351
|
+
/* Only one way to go, so cotinue on the path */
|
|
1352
|
+
if (availableLEs.length === 1) {
|
|
1353
|
+
nextEvent = availableLEs[0].otherSE;
|
|
1354
|
+
break;
|
|
1355
|
+
}
|
|
1256
1356
|
|
|
1257
|
-
|
|
1258
|
-
|
|
1357
|
+
/* We must have an intersection. Check for a completed loop */
|
|
1358
|
+
let indexLE = null;
|
|
1359
|
+
for (let j = 0, jMax = intersectionLEs.length; j < jMax; j++) {
|
|
1360
|
+
if (intersectionLEs[j].point === event.point) {
|
|
1361
|
+
indexLE = j;
|
|
1259
1362
|
break;
|
|
1260
1363
|
}
|
|
1261
|
-
/* We must have an intersection. Check for a completed loop */
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
var indexLE = null;
|
|
1265
|
-
|
|
1266
|
-
for (var j = 0, jMax = intersectionLEs.length; j < jMax; j++) {
|
|
1267
|
-
if (intersectionLEs[j].point === event.point) {
|
|
1268
|
-
indexLE = j;
|
|
1269
|
-
break;
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
/* Found a completed loop. Cut that off and make a ring */
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
if (indexLE !== null) {
|
|
1276
|
-
var intersectionLE = intersectionLEs.splice(indexLE)[0];
|
|
1277
|
-
var ringEvents = events.splice(intersectionLE.index);
|
|
1278
|
-
ringEvents.unshift(ringEvents[0].otherSE);
|
|
1279
|
-
ringsOut.push(new RingOut(ringEvents.reverse()));
|
|
1280
|
-
continue;
|
|
1281
|
-
}
|
|
1282
|
-
/* register the intersection */
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
intersectionLEs.push({
|
|
1286
|
-
index: events.length,
|
|
1287
|
-
point: event.point
|
|
1288
|
-
});
|
|
1289
|
-
/* Choose the left-most option to continue the walk */
|
|
1290
|
-
|
|
1291
|
-
var comparator = event.getLeftmostComparator(prevEvent);
|
|
1292
|
-
nextEvent = availableLEs.sort(comparator)[0].otherSE;
|
|
1293
|
-
break;
|
|
1294
1364
|
}
|
|
1365
|
+
/* Found a completed loop. Cut that off and make a ring */
|
|
1366
|
+
if (indexLE !== null) {
|
|
1367
|
+
const intersectionLE = intersectionLEs.splice(indexLE)[0];
|
|
1368
|
+
const ringEvents = events.splice(intersectionLE.index);
|
|
1369
|
+
ringEvents.unshift(ringEvents[0].otherSE);
|
|
1370
|
+
ringsOut.push(new RingOut(ringEvents.reverse()));
|
|
1371
|
+
continue;
|
|
1372
|
+
}
|
|
1373
|
+
/* register the intersection */
|
|
1374
|
+
intersectionLEs.push({
|
|
1375
|
+
index: events.length,
|
|
1376
|
+
point: event.point
|
|
1377
|
+
});
|
|
1378
|
+
/* Choose the left-most option to continue the walk */
|
|
1379
|
+
const comparator = event.getLeftmostComparator(prevEvent);
|
|
1380
|
+
nextEvent = availableLEs.sort(comparator)[0].otherSE;
|
|
1381
|
+
break;
|
|
1295
1382
|
}
|
|
1296
|
-
|
|
1297
|
-
ringsOut.push(new RingOut(events));
|
|
1298
1383
|
}
|
|
1299
|
-
|
|
1300
|
-
return ringsOut;
|
|
1384
|
+
ringsOut.push(new RingOut(events));
|
|
1301
1385
|
}
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
_classCallCheck(this, RingOut);
|
|
1306
|
-
|
|
1386
|
+
return ringsOut;
|
|
1387
|
+
}
|
|
1388
|
+
constructor(events) {
|
|
1307
1389
|
this.events = events;
|
|
1308
|
-
|
|
1309
|
-
for (var i = 0, iMax = events.length; i < iMax; i++) {
|
|
1390
|
+
for (let i = 0, iMax = events.length; i < iMax; i++) {
|
|
1310
1391
|
events[i].segment.ringOut = this;
|
|
1311
1392
|
}
|
|
1312
|
-
|
|
1313
1393
|
this.poly = null;
|
|
1314
1394
|
}
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
var _nextPt = this.events[i + 1].point;
|
|
1326
|
-
if (compareVectorAngles(_pt, prevPt, _nextPt) === 0) continue;
|
|
1327
|
-
points.push(_pt);
|
|
1328
|
-
prevPt = _pt;
|
|
1329
|
-
} // ring was all (within rounding error of angle calc) colinear points
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
if (points.length === 1) return null; // check if the starting point is necessary
|
|
1333
|
-
|
|
1334
|
-
var pt = points[0];
|
|
1335
|
-
var nextPt = points[1];
|
|
1336
|
-
if (compareVectorAngles(pt, prevPt, nextPt) === 0) points.shift();
|
|
1337
|
-
points.push(points[0]);
|
|
1338
|
-
var step = this.isExteriorRing() ? 1 : -1;
|
|
1339
|
-
var iStart = this.isExteriorRing() ? 0 : points.length - 1;
|
|
1340
|
-
var iEnd = this.isExteriorRing() ? points.length : -1;
|
|
1341
|
-
var orderedPoints = [];
|
|
1342
|
-
|
|
1343
|
-
for (var _i = iStart; _i != iEnd; _i += step) {
|
|
1344
|
-
orderedPoints.push([points[_i].x, points[_i].y]);
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
return orderedPoints;
|
|
1395
|
+
getGeom() {
|
|
1396
|
+
// Remove superfluous points (ie extra points along a straight line),
|
|
1397
|
+
let prevPt = this.events[0].point;
|
|
1398
|
+
const points = [prevPt];
|
|
1399
|
+
for (let i = 1, iMax = this.events.length - 1; i < iMax; i++) {
|
|
1400
|
+
const pt = this.events[i].point;
|
|
1401
|
+
const nextPt = this.events[i + 1].point;
|
|
1402
|
+
if (compareVectorAngles(pt, prevPt, nextPt) === 0) continue;
|
|
1403
|
+
points.push(pt);
|
|
1404
|
+
prevPt = pt;
|
|
1348
1405
|
}
|
|
1349
|
-
}, {
|
|
1350
|
-
key: "isExteriorRing",
|
|
1351
|
-
value: function isExteriorRing() {
|
|
1352
|
-
if (this._isExteriorRing === undefined) {
|
|
1353
|
-
var enclosing = this.enclosingRing();
|
|
1354
|
-
this._isExteriorRing = enclosing ? !enclosing.isExteriorRing() : true;
|
|
1355
|
-
}
|
|
1356
1406
|
|
|
1357
|
-
|
|
1407
|
+
// ring was all (within rounding error of angle calc) colinear points
|
|
1408
|
+
if (points.length === 1) return null;
|
|
1409
|
+
|
|
1410
|
+
// check if the starting point is necessary
|
|
1411
|
+
const pt = points[0];
|
|
1412
|
+
const nextPt = points[1];
|
|
1413
|
+
if (compareVectorAngles(pt, prevPt, nextPt) === 0) points.shift();
|
|
1414
|
+
points.push(points[0]);
|
|
1415
|
+
const step = this.isExteriorRing() ? 1 : -1;
|
|
1416
|
+
const iStart = this.isExteriorRing() ? 0 : points.length - 1;
|
|
1417
|
+
const iEnd = this.isExteriorRing() ? points.length : -1;
|
|
1418
|
+
const orderedPoints = [];
|
|
1419
|
+
for (let i = iStart; i != iEnd; i += step) orderedPoints.push([points[i].x, points[i].y]);
|
|
1420
|
+
return orderedPoints;
|
|
1421
|
+
}
|
|
1422
|
+
isExteriorRing() {
|
|
1423
|
+
if (this._isExteriorRing === undefined) {
|
|
1424
|
+
const enclosing = this.enclosingRing();
|
|
1425
|
+
this._isExteriorRing = enclosing ? !enclosing.isExteriorRing() : true;
|
|
1358
1426
|
}
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
}
|
|
1365
|
-
|
|
1366
|
-
return this._enclosingRing;
|
|
1427
|
+
return this._isExteriorRing;
|
|
1428
|
+
}
|
|
1429
|
+
enclosingRing() {
|
|
1430
|
+
if (this._enclosingRing === undefined) {
|
|
1431
|
+
this._enclosingRing = this._calcEnclosingRing();
|
|
1367
1432
|
}
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
}, {
|
|
1371
|
-
key: "_calcEnclosingRing",
|
|
1372
|
-
value: function _calcEnclosingRing() {
|
|
1373
|
-
// start with the ealier sweep line event so that the prevSeg
|
|
1374
|
-
// chain doesn't lead us inside of a loop of ours
|
|
1375
|
-
var leftMostEvt = this.events[0];
|
|
1433
|
+
return this._enclosingRing;
|
|
1434
|
+
}
|
|
1376
1435
|
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1436
|
+
/* Returns the ring that encloses this one, if any */
|
|
1437
|
+
_calcEnclosingRing() {
|
|
1438
|
+
// start with the ealier sweep line event so that the prevSeg
|
|
1439
|
+
// chain doesn't lead us inside of a loop of ours
|
|
1440
|
+
let leftMostEvt = this.events[0];
|
|
1441
|
+
for (let i = 1, iMax = this.events.length; i < iMax; i++) {
|
|
1442
|
+
const evt = this.events[i];
|
|
1443
|
+
if (SweepEvent.compare(leftMostEvt, evt) > 0) leftMostEvt = evt;
|
|
1444
|
+
}
|
|
1445
|
+
let prevSeg = leftMostEvt.segment.prevInResult();
|
|
1446
|
+
let prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null;
|
|
1447
|
+
while (true) {
|
|
1448
|
+
// no segment found, thus no ring can enclose us
|
|
1449
|
+
if (!prevSeg) return null;
|
|
1450
|
+
|
|
1451
|
+
// no segments below prev segment found, thus the ring of the prev
|
|
1452
|
+
// segment must loop back around and enclose us
|
|
1453
|
+
if (!prevPrevSeg) return prevSeg.ringOut;
|
|
1454
|
+
|
|
1455
|
+
// if the two segments are of different rings, the ring of the prev
|
|
1456
|
+
// segment must either loop around us or the ring of the prev prev
|
|
1457
|
+
// seg, which would make us and the ring of the prev peers
|
|
1458
|
+
if (prevPrevSeg.ringOut !== prevSeg.ringOut) {
|
|
1459
|
+
if (prevPrevSeg.ringOut.enclosingRing() !== prevSeg.ringOut) {
|
|
1460
|
+
return prevSeg.ringOut;
|
|
1461
|
+
} else return prevSeg.ringOut.enclosingRing();
|
|
1380
1462
|
}
|
|
1381
1463
|
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
// no segment found, thus no ring can enclose us
|
|
1387
|
-
if (!prevSeg) return null; // no segments below prev segment found, thus the ring of the prev
|
|
1388
|
-
// segment must loop back around and enclose us
|
|
1389
|
-
|
|
1390
|
-
if (!prevPrevSeg) return prevSeg.ringOut; // if the two segments are of different rings, the ring of the prev
|
|
1391
|
-
// segment must either loop around us or the ring of the prev prev
|
|
1392
|
-
// seg, which would make us and the ring of the prev peers
|
|
1393
|
-
|
|
1394
|
-
if (prevPrevSeg.ringOut !== prevSeg.ringOut) {
|
|
1395
|
-
if (prevPrevSeg.ringOut.enclosingRing() !== prevSeg.ringOut) {
|
|
1396
|
-
return prevSeg.ringOut;
|
|
1397
|
-
} else return prevSeg.ringOut.enclosingRing();
|
|
1398
|
-
} // two segments are from the same ring, so this was a penisula
|
|
1399
|
-
// of that ring. iterate downward, keep searching
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
prevSeg = prevPrevSeg.prevInResult();
|
|
1403
|
-
prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null;
|
|
1404
|
-
}
|
|
1464
|
+
// two segments are from the same ring, so this was a penisula
|
|
1465
|
+
// of that ring. iterate downward, keep searching
|
|
1466
|
+
prevSeg = prevPrevSeg.prevInResult();
|
|
1467
|
+
prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null;
|
|
1405
1468
|
}
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
var PolyOut = /*#__PURE__*/function () {
|
|
1411
|
-
function PolyOut(exteriorRing) {
|
|
1412
|
-
_classCallCheck(this, PolyOut);
|
|
1413
|
-
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
class PolyOut {
|
|
1472
|
+
constructor(exteriorRing) {
|
|
1414
1473
|
this.exteriorRing = exteriorRing;
|
|
1415
1474
|
exteriorRing.poly = this;
|
|
1416
1475
|
this.interiorRings = [];
|
|
1417
1476
|
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
for (var i = 0, iMax = this.interiorRings.length; i < iMax; i++) {
|
|
1433
|
-
var ringGeom = this.interiorRings[i].getGeom(); // interior ring was all (within rounding error of angle calc) colinear points
|
|
1434
|
-
|
|
1435
|
-
if (ringGeom === null) continue;
|
|
1436
|
-
geom.push(ringGeom);
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
return geom;
|
|
1477
|
+
addInterior(ring) {
|
|
1478
|
+
this.interiorRings.push(ring);
|
|
1479
|
+
ring.poly = this;
|
|
1480
|
+
}
|
|
1481
|
+
getGeom() {
|
|
1482
|
+
const geom = [this.exteriorRing.getGeom()];
|
|
1483
|
+
// exterior ring was all (within rounding error of angle calc) colinear points
|
|
1484
|
+
if (geom[0] === null) return null;
|
|
1485
|
+
for (let i = 0, iMax = this.interiorRings.length; i < iMax; i++) {
|
|
1486
|
+
const ringGeom = this.interiorRings[i].getGeom();
|
|
1487
|
+
// interior ring was all (within rounding error of angle calc) colinear points
|
|
1488
|
+
if (ringGeom === null) continue;
|
|
1489
|
+
geom.push(ringGeom);
|
|
1440
1490
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
function MultiPolyOut(rings) {
|
|
1447
|
-
_classCallCheck(this, MultiPolyOut);
|
|
1448
|
-
|
|
1491
|
+
return geom;
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
class MultiPolyOut {
|
|
1495
|
+
constructor(rings) {
|
|
1449
1496
|
this.rings = rings;
|
|
1450
1497
|
this.polys = this._composePolys(rings);
|
|
1451
1498
|
}
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
var polyGeom = this.polys[i].getGeom(); // exterior ring was all (within rounding error of angle calc) colinear points
|
|
1460
|
-
|
|
1461
|
-
if (polyGeom === null) continue;
|
|
1462
|
-
geom.push(polyGeom);
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
return geom;
|
|
1499
|
+
getGeom() {
|
|
1500
|
+
const geom = [];
|
|
1501
|
+
for (let i = 0, iMax = this.polys.length; i < iMax; i++) {
|
|
1502
|
+
const polyGeom = this.polys[i].getGeom();
|
|
1503
|
+
// exterior ring was all (within rounding error of angle calc) colinear points
|
|
1504
|
+
if (polyGeom === null) continue;
|
|
1505
|
+
geom.push(polyGeom);
|
|
1466
1506
|
}
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
enclosingRing.poly.addInterior(ring);
|
|
1479
|
-
}
|
|
1507
|
+
return geom;
|
|
1508
|
+
}
|
|
1509
|
+
_composePolys(rings) {
|
|
1510
|
+
const polys = [];
|
|
1511
|
+
for (let i = 0, iMax = rings.length; i < iMax; i++) {
|
|
1512
|
+
const ring = rings[i];
|
|
1513
|
+
if (ring.poly) continue;
|
|
1514
|
+
if (ring.isExteriorRing()) polys.push(new PolyOut(ring));else {
|
|
1515
|
+
const enclosingRing = ring.enclosingRing();
|
|
1516
|
+
if (!enclosingRing.poly) polys.push(new PolyOut(enclosingRing));
|
|
1517
|
+
enclosingRing.poly.addInterior(ring);
|
|
1480
1518
|
}
|
|
1481
|
-
|
|
1482
|
-
return polys;
|
|
1483
1519
|
}
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
}();
|
|
1520
|
+
return polys;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1488
1523
|
|
|
1489
1524
|
/**
|
|
1490
1525
|
* NOTE: We must be careful not to change any segments while
|
|
@@ -1497,328 +1532,270 @@ var MultiPolyOut = /*#__PURE__*/function () {
|
|
|
1497
1532
|
* it sometimes does.)
|
|
1498
1533
|
*/
|
|
1499
1534
|
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
_classCallCheck(this, SweepLine);
|
|
1505
|
-
|
|
1535
|
+
class SweepLine {
|
|
1536
|
+
constructor(queue) {
|
|
1537
|
+
let comparator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Segment.compare;
|
|
1506
1538
|
this.queue = queue;
|
|
1507
|
-
this.tree = new SplayTree__default[
|
|
1539
|
+
this.tree = new SplayTree__default["default"](comparator);
|
|
1508
1540
|
this.segments = [];
|
|
1509
1541
|
}
|
|
1542
|
+
process(event) {
|
|
1543
|
+
const segment = event.segment;
|
|
1544
|
+
const newEvents = [];
|
|
1545
|
+
|
|
1546
|
+
// if we've already been consumed by another segment,
|
|
1547
|
+
// clean up our body parts and get out
|
|
1548
|
+
if (event.consumedBy) {
|
|
1549
|
+
if (event.isLeft) this.queue.remove(event.otherSE);else this.tree.remove(segment);
|
|
1550
|
+
return newEvents;
|
|
1551
|
+
}
|
|
1552
|
+
const node = event.isLeft ? this.tree.add(segment) : this.tree.find(segment);
|
|
1553
|
+
if (!node) throw new Error(`Unable to find segment #${segment.id} ` + `[${segment.leftSE.point.x}, ${segment.leftSE.point.y}] -> ` + `[${segment.rightSE.point.x}, ${segment.rightSE.point.y}] ` + "in SweepLine tree.");
|
|
1554
|
+
let prevNode = node;
|
|
1555
|
+
let nextNode = node;
|
|
1556
|
+
let prevSeg = undefined;
|
|
1557
|
+
let nextSeg = undefined;
|
|
1558
|
+
|
|
1559
|
+
// skip consumed segments still in tree
|
|
1560
|
+
while (prevSeg === undefined) {
|
|
1561
|
+
prevNode = this.tree.prev(prevNode);
|
|
1562
|
+
if (prevNode === null) prevSeg = null;else if (prevNode.key.consumedBy === undefined) prevSeg = prevNode.key;
|
|
1563
|
+
}
|
|
1510
1564
|
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
var prevSeg = undefined;
|
|
1528
|
-
var nextSeg = undefined; // skip consumed segments still in tree
|
|
1529
|
-
|
|
1530
|
-
while (prevSeg === undefined) {
|
|
1531
|
-
prevNode = this.tree.prev(prevNode);
|
|
1532
|
-
if (prevNode === null) prevSeg = null;else if (prevNode.key.consumedBy === undefined) prevSeg = prevNode.key;
|
|
1533
|
-
} // skip consumed segments still in tree
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
while (nextSeg === undefined) {
|
|
1537
|
-
nextNode = this.tree.next(nextNode);
|
|
1538
|
-
if (nextNode === null) nextSeg = null;else if (nextNode.key.consumedBy === undefined) nextSeg = nextNode.key;
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
if (event.isLeft) {
|
|
1542
|
-
// Check for intersections against the previous segment in the sweep line
|
|
1543
|
-
var prevMySplitter = null;
|
|
1544
|
-
|
|
1545
|
-
if (prevSeg) {
|
|
1546
|
-
var prevInter = prevSeg.getIntersection(segment);
|
|
1547
|
-
|
|
1548
|
-
if (prevInter !== null) {
|
|
1549
|
-
if (!segment.isAnEndpoint(prevInter)) prevMySplitter = prevInter;
|
|
1550
|
-
|
|
1551
|
-
if (!prevSeg.isAnEndpoint(prevInter)) {
|
|
1552
|
-
var newEventsFromSplit = this._splitSafely(prevSeg, prevInter);
|
|
1553
|
-
|
|
1554
|
-
for (var i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {
|
|
1555
|
-
newEvents.push(newEventsFromSplit[i]);
|
|
1556
|
-
}
|
|
1565
|
+
// skip consumed segments still in tree
|
|
1566
|
+
while (nextSeg === undefined) {
|
|
1567
|
+
nextNode = this.tree.next(nextNode);
|
|
1568
|
+
if (nextNode === null) nextSeg = null;else if (nextNode.key.consumedBy === undefined) nextSeg = nextNode.key;
|
|
1569
|
+
}
|
|
1570
|
+
if (event.isLeft) {
|
|
1571
|
+
// Check for intersections against the previous segment in the sweep line
|
|
1572
|
+
let prevMySplitter = null;
|
|
1573
|
+
if (prevSeg) {
|
|
1574
|
+
const prevInter = prevSeg.getIntersection(segment);
|
|
1575
|
+
if (prevInter !== null) {
|
|
1576
|
+
if (!segment.isAnEndpoint(prevInter)) prevMySplitter = prevInter;
|
|
1577
|
+
if (!prevSeg.isAnEndpoint(prevInter)) {
|
|
1578
|
+
const newEventsFromSplit = this._splitSafely(prevSeg, prevInter);
|
|
1579
|
+
for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {
|
|
1580
|
+
newEvents.push(newEventsFromSplit[i]);
|
|
1557
1581
|
}
|
|
1558
1582
|
}
|
|
1559
|
-
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
var nextMySplitter = null;
|
|
1563
|
-
|
|
1564
|
-
if (nextSeg) {
|
|
1565
|
-
var nextInter = nextSeg.getIntersection(segment);
|
|
1566
|
-
|
|
1567
|
-
if (nextInter !== null) {
|
|
1568
|
-
if (!segment.isAnEndpoint(nextInter)) nextMySplitter = nextInter;
|
|
1569
|
-
|
|
1570
|
-
if (!nextSeg.isAnEndpoint(nextInter)) {
|
|
1571
|
-
var _newEventsFromSplit = this._splitSafely(nextSeg, nextInter);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1572
1585
|
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1586
|
+
// Check for intersections against the next segment in the sweep line
|
|
1587
|
+
let nextMySplitter = null;
|
|
1588
|
+
if (nextSeg) {
|
|
1589
|
+
const nextInter = nextSeg.getIntersection(segment);
|
|
1590
|
+
if (nextInter !== null) {
|
|
1591
|
+
if (!segment.isAnEndpoint(nextInter)) nextMySplitter = nextInter;
|
|
1592
|
+
if (!nextSeg.isAnEndpoint(nextInter)) {
|
|
1593
|
+
const newEventsFromSplit = this._splitSafely(nextSeg, nextInter);
|
|
1594
|
+
for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {
|
|
1595
|
+
newEvents.push(newEventsFromSplit[i]);
|
|
1576
1596
|
}
|
|
1577
1597
|
}
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
// The other intersection will be handled in a future process().
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
if (prevMySplitter !== null || nextMySplitter !== null) {
|
|
1584
|
-
var mySplitter = null;
|
|
1585
|
-
if (prevMySplitter === null) mySplitter = nextMySplitter;else if (nextMySplitter === null) mySplitter = prevMySplitter;else {
|
|
1586
|
-
var cmpSplitters = SweepEvent.comparePoints(prevMySplitter, nextMySplitter);
|
|
1587
|
-
mySplitter = cmpSplitters <= 0 ? prevMySplitter : nextMySplitter;
|
|
1588
|
-
} // Rounding errors can cause changes in ordering,
|
|
1589
|
-
// so remove afected segments and right sweep events before splitting
|
|
1590
|
-
|
|
1591
|
-
this.queue.remove(segment.rightSE);
|
|
1592
|
-
newEvents.push(segment.rightSE);
|
|
1593
|
-
|
|
1594
|
-
var _newEventsFromSplit2 = segment.split(mySplitter);
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1595
1600
|
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1601
|
+
// For simplicity, even if we find more than one intersection we only
|
|
1602
|
+
// spilt on the 'earliest' (sweep-line style) of the intersections.
|
|
1603
|
+
// The other intersection will be handled in a future process().
|
|
1604
|
+
if (prevMySplitter !== null || nextMySplitter !== null) {
|
|
1605
|
+
let mySplitter = null;
|
|
1606
|
+
if (prevMySplitter === null) mySplitter = nextMySplitter;else if (nextMySplitter === null) mySplitter = prevMySplitter;else {
|
|
1607
|
+
const cmpSplitters = SweepEvent.comparePoints(prevMySplitter, nextMySplitter);
|
|
1608
|
+
mySplitter = cmpSplitters <= 0 ? prevMySplitter : nextMySplitter;
|
|
1599
1609
|
}
|
|
1600
1610
|
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
// done with left event
|
|
1609
|
-
this.segments.push(segment);
|
|
1610
|
-
segment.prev = prevSeg;
|
|
1611
|
+
// Rounding errors can cause changes in ordering,
|
|
1612
|
+
// so remove afected segments and right sweep events before splitting
|
|
1613
|
+
this.queue.remove(segment.rightSE);
|
|
1614
|
+
newEvents.push(segment.rightSE);
|
|
1615
|
+
const newEventsFromSplit = segment.split(mySplitter);
|
|
1616
|
+
for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {
|
|
1617
|
+
newEvents.push(newEventsFromSplit[i]);
|
|
1611
1618
|
}
|
|
1619
|
+
}
|
|
1620
|
+
if (newEvents.length > 0) {
|
|
1621
|
+
// We found some intersections, so re-do the current event to
|
|
1622
|
+
// make sure sweep line ordering is totally consistent for later
|
|
1623
|
+
// use with the segment 'prev' pointers
|
|
1624
|
+
this.tree.remove(segment);
|
|
1625
|
+
newEvents.push(event);
|
|
1612
1626
|
} else {
|
|
1613
|
-
// event
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1627
|
+
// done with left event
|
|
1628
|
+
this.segments.push(segment);
|
|
1629
|
+
segment.prev = prevSeg;
|
|
1630
|
+
}
|
|
1631
|
+
} else {
|
|
1632
|
+
// event.isRight
|
|
1633
|
+
|
|
1634
|
+
// since we're about to be removed from the sweep line, check for
|
|
1635
|
+
// intersections between our previous and next segments
|
|
1636
|
+
if (prevSeg && nextSeg) {
|
|
1637
|
+
const inter = prevSeg.getIntersection(nextSeg);
|
|
1638
|
+
if (inter !== null) {
|
|
1639
|
+
if (!prevSeg.isAnEndpoint(inter)) {
|
|
1640
|
+
const newEventsFromSplit = this._splitSafely(prevSeg, inter);
|
|
1641
|
+
for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {
|
|
1642
|
+
newEvents.push(newEventsFromSplit[i]);
|
|
1626
1643
|
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
newEvents.push(_newEventsFromSplit4[_i4]);
|
|
1633
|
-
}
|
|
1644
|
+
}
|
|
1645
|
+
if (!nextSeg.isAnEndpoint(inter)) {
|
|
1646
|
+
const newEventsFromSplit = this._splitSafely(nextSeg, inter);
|
|
1647
|
+
for (let i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {
|
|
1648
|
+
newEvents.push(newEventsFromSplit[i]);
|
|
1634
1649
|
}
|
|
1635
1650
|
}
|
|
1636
1651
|
}
|
|
1637
|
-
|
|
1638
|
-
this.tree.remove(segment);
|
|
1639
1652
|
}
|
|
1640
|
-
|
|
1641
|
-
return newEvents;
|
|
1642
|
-
}
|
|
1643
|
-
/* Safely split a segment that is currently in the datastructures
|
|
1644
|
-
* IE - a segment other than the one that is currently being processed. */
|
|
1645
|
-
|
|
1646
|
-
}, {
|
|
1647
|
-
key: "_splitSafely",
|
|
1648
|
-
value: function _splitSafely(seg, pt) {
|
|
1649
|
-
// Rounding errors can cause changes in ordering,
|
|
1650
|
-
// so remove afected segments and right sweep events before splitting
|
|
1651
|
-
// removeNode() doesn't work, so have re-find the seg
|
|
1652
|
-
// https://github.com/w8r/splay-tree/pull/5
|
|
1653
|
-
this.tree.remove(seg);
|
|
1654
|
-
var rightSE = seg.rightSE;
|
|
1655
|
-
this.queue.remove(rightSE);
|
|
1656
|
-
var newEvents = seg.split(pt);
|
|
1657
|
-
newEvents.push(rightSE); // splitting can trigger consumption
|
|
1658
|
-
|
|
1659
|
-
if (seg.consumedBy === undefined) this.tree.insert(seg);
|
|
1660
|
-
return newEvents;
|
|
1653
|
+
this.tree.remove(segment);
|
|
1661
1654
|
}
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
return SweepLine;
|
|
1665
|
-
}();
|
|
1666
|
-
|
|
1667
|
-
var POLYGON_CLIPPING_MAX_QUEUE_SIZE = typeof process !== 'undefined' && process.env.POLYGON_CLIPPING_MAX_QUEUE_SIZE || 1000000;
|
|
1668
|
-
var POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS = typeof process !== 'undefined' && process.env.POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS || 1000000;
|
|
1669
|
-
var Operation = /*#__PURE__*/function () {
|
|
1670
|
-
function Operation() {
|
|
1671
|
-
_classCallCheck(this, Operation);
|
|
1655
|
+
return newEvents;
|
|
1672
1656
|
}
|
|
1673
1657
|
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
* multiploygon. */
|
|
1692
|
-
|
|
1693
|
-
if (operation.type === 'difference') {
|
|
1694
|
-
// in place removal
|
|
1695
|
-
var subject = multipolys[0];
|
|
1696
|
-
var _i = 1;
|
|
1697
|
-
|
|
1698
|
-
while (_i < multipolys.length) {
|
|
1699
|
-
if (getBboxOverlap(multipolys[_i].bbox, subject.bbox) !== null) _i++;else multipolys.splice(_i, 1);
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1702
|
-
/* BBox optimization for intersection operation
|
|
1703
|
-
* If we can find any pair of multipolygons whose bbox does not overlap,
|
|
1704
|
-
* then the result will be empty. */
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
if (operation.type === 'intersection') {
|
|
1708
|
-
// TODO: this is O(n^2) in number of polygons. By sorting the bboxes,
|
|
1709
|
-
// it could be optimized to O(n * ln(n))
|
|
1710
|
-
for (var _i2 = 0, _iMax = multipolys.length; _i2 < _iMax; _i2++) {
|
|
1711
|
-
var mpA = multipolys[_i2];
|
|
1658
|
+
/* Safely split a segment that is currently in the datastructures
|
|
1659
|
+
* IE - a segment other than the one that is currently being processed. */
|
|
1660
|
+
_splitSafely(seg, pt) {
|
|
1661
|
+
// Rounding errors can cause changes in ordering,
|
|
1662
|
+
// so remove afected segments and right sweep events before splitting
|
|
1663
|
+
// removeNode() doesn't work, so have re-find the seg
|
|
1664
|
+
// https://github.com/w8r/splay-tree/pull/5
|
|
1665
|
+
this.tree.remove(seg);
|
|
1666
|
+
const rightSE = seg.rightSE;
|
|
1667
|
+
this.queue.remove(rightSE);
|
|
1668
|
+
const newEvents = seg.split(pt);
|
|
1669
|
+
newEvents.push(rightSE);
|
|
1670
|
+
// splitting can trigger consumption
|
|
1671
|
+
if (seg.consumedBy === undefined) this.tree.add(seg);
|
|
1672
|
+
return newEvents;
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1712
1675
|
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1676
|
+
// Limits on iterative processes to prevent infinite loops - usually caused by floating-point math round-off errors.
|
|
1677
|
+
const POLYGON_CLIPPING_MAX_QUEUE_SIZE = typeof process !== "undefined" && process.env.POLYGON_CLIPPING_MAX_QUEUE_SIZE || 1000000;
|
|
1678
|
+
const POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS = typeof process !== "undefined" && process.env.POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS || 1000000;
|
|
1679
|
+
class Operation {
|
|
1680
|
+
run(type, geom, moreGeoms) {
|
|
1681
|
+
operation.type = type;
|
|
1682
|
+
rounder.reset();
|
|
1683
|
+
|
|
1684
|
+
/* Convert inputs to MultiPoly objects */
|
|
1685
|
+
const multipolys = [new MultiPolyIn(geom, true)];
|
|
1686
|
+
for (let i = 0, iMax = moreGeoms.length; i < iMax; i++) {
|
|
1687
|
+
multipolys.push(new MultiPolyIn(moreGeoms[i], false));
|
|
1688
|
+
}
|
|
1689
|
+
operation.numMultiPolys = multipolys.length;
|
|
1690
|
+
|
|
1691
|
+
/* BBox optimization for difference operation
|
|
1692
|
+
* If the bbox of a multipolygon that's part of the clipping doesn't
|
|
1693
|
+
* intersect the bbox of the subject at all, we can just drop that
|
|
1694
|
+
* multiploygon. */
|
|
1695
|
+
if (operation.type === "difference") {
|
|
1696
|
+
// in place removal
|
|
1697
|
+
const subject = multipolys[0];
|
|
1698
|
+
let i = 1;
|
|
1699
|
+
while (i < multipolys.length) {
|
|
1700
|
+
if (getBboxOverlap(multipolys[i].bbox, subject.bbox) !== null) i++;else multipolys.splice(i, 1);
|
|
1717
1701
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
var queue = new SplayTree__default['default'](SweepEvent.compare);
|
|
1722
|
-
|
|
1723
|
-
for (var _i3 = 0, _iMax2 = multipolys.length; _i3 < _iMax2; _i3++) {
|
|
1724
|
-
var sweepEvents = multipolys[_i3].getSweepEvents();
|
|
1725
|
-
|
|
1726
|
-
for (var _j = 0, _jMax = sweepEvents.length; _j < _jMax; _j++) {
|
|
1727
|
-
queue.insert(sweepEvents[_j]);
|
|
1702
|
+
}
|
|
1728
1703
|
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1704
|
+
/* BBox optimization for intersection operation
|
|
1705
|
+
* If we can find any pair of multipolygons whose bbox does not overlap,
|
|
1706
|
+
* then the result will be empty. */
|
|
1707
|
+
if (operation.type === "intersection") {
|
|
1708
|
+
// TODO: this is O(n^2) in number of polygons. By sorting the bboxes,
|
|
1709
|
+
// it could be optimized to O(n * ln(n))
|
|
1710
|
+
for (let i = 0, iMax = multipolys.length; i < iMax; i++) {
|
|
1711
|
+
const mpA = multipolys[i];
|
|
1712
|
+
for (let j = i + 1, jMax = multipolys.length; j < jMax; j++) {
|
|
1713
|
+
if (getBboxOverlap(mpA.bbox, multipolys[j].bbox) === null) return [];
|
|
1733
1714
|
}
|
|
1734
1715
|
}
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
var sweepLine = new SweepLine(queue);
|
|
1739
|
-
var prevQueueSize = queue.size;
|
|
1740
|
-
var node = queue.pop();
|
|
1741
|
-
|
|
1742
|
-
while (node) {
|
|
1743
|
-
var evt = node.key;
|
|
1744
|
-
|
|
1745
|
-
if (queue.size === prevQueueSize) {
|
|
1746
|
-
// prevents an infinite loop, an otherwise common manifestation of bugs
|
|
1747
|
-
var seg = evt.segment;
|
|
1748
|
-
throw new Error("Unable to pop() ".concat(evt.isLeft ? 'left' : 'right', " SweepEvent ") + "[".concat(evt.point.x, ", ").concat(evt.point.y, "] from segment #").concat(seg.id, " ") + "[".concat(seg.leftSE.point.x, ", ").concat(seg.leftSE.point.y, "] -> ") + "[".concat(seg.rightSE.point.x, ", ").concat(seg.rightSE.point.y, "] from queue. ") + 'Please file a bug report.');
|
|
1749
|
-
}
|
|
1716
|
+
}
|
|
1750
1717
|
|
|
1718
|
+
/* Put segment endpoints in a priority queue */
|
|
1719
|
+
const queue = new SplayTree__default["default"](SweepEvent.compare);
|
|
1720
|
+
for (let i = 0, iMax = multipolys.length; i < iMax; i++) {
|
|
1721
|
+
const sweepEvents = multipolys[i].getSweepEvents();
|
|
1722
|
+
for (let j = 0, jMax = sweepEvents.length; j < jMax; j++) {
|
|
1723
|
+
queue.insert(sweepEvents[j]);
|
|
1751
1724
|
if (queue.size > POLYGON_CLIPPING_MAX_QUEUE_SIZE) {
|
|
1752
1725
|
// prevents an infinite loop, an otherwise common manifestation of bugs
|
|
1753
|
-
throw new Error(
|
|
1754
|
-
}
|
|
1755
|
-
|
|
1756
|
-
if (sweepLine.segments.length > POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS) {
|
|
1757
|
-
// prevents an infinite loop, an otherwise common manifestation of bugs
|
|
1758
|
-
throw new Error('Infinite loop when passing sweep line over endpoints ' + '(too many sweep line segments). Please file a bug report.');
|
|
1726
|
+
throw new Error("Infinite loop when putting segment endpoints in a priority queue " + "(queue size too big).");
|
|
1759
1727
|
}
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1760
1730
|
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1731
|
+
/* Pass the sweep line over those endpoints */
|
|
1732
|
+
const sweepLine = new SweepLine(queue);
|
|
1733
|
+
let prevQueueSize = queue.size;
|
|
1734
|
+
let node = queue.pop();
|
|
1735
|
+
while (node) {
|
|
1736
|
+
const evt = node.key;
|
|
1737
|
+
if (queue.size === prevQueueSize) {
|
|
1738
|
+
// prevents an infinite loop, an otherwise common manifestation of bugs
|
|
1739
|
+
const seg = evt.segment;
|
|
1740
|
+
throw new Error(`Unable to pop() ${evt.isLeft ? "left" : "right"} SweepEvent ` + `[${evt.point.x}, ${evt.point.y}] from segment #${seg.id} ` + `[${seg.leftSE.point.x}, ${seg.leftSE.point.y}] -> ` + `[${seg.rightSE.point.x}, ${seg.rightSE.point.y}] from queue.`);
|
|
1741
|
+
}
|
|
1742
|
+
if (queue.size > POLYGON_CLIPPING_MAX_QUEUE_SIZE) {
|
|
1743
|
+
// prevents an infinite loop, an otherwise common manifestation of bugs
|
|
1744
|
+
throw new Error("Infinite loop when passing sweep line over endpoints " + "(queue size too big).");
|
|
1745
|
+
}
|
|
1746
|
+
if (sweepLine.segments.length > POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS) {
|
|
1747
|
+
// prevents an infinite loop, an otherwise common manifestation of bugs
|
|
1748
|
+
throw new Error("Infinite loop when passing sweep line over endpoints " + "(too many sweep line segments).");
|
|
1749
|
+
}
|
|
1750
|
+
const newEvents = sweepLine.process(evt);
|
|
1751
|
+
for (let i = 0, iMax = newEvents.length; i < iMax; i++) {
|
|
1752
|
+
const evt = newEvents[i];
|
|
1753
|
+
if (evt.consumedBy === undefined) queue.insert(evt);
|
|
1754
|
+
}
|
|
1755
|
+
prevQueueSize = queue.size;
|
|
1756
|
+
node = queue.pop();
|
|
1779
1757
|
}
|
|
1780
|
-
}]);
|
|
1781
1758
|
|
|
1782
|
-
|
|
1783
|
-
|
|
1759
|
+
// free some memory we don't need anymore
|
|
1760
|
+
rounder.reset();
|
|
1761
|
+
|
|
1762
|
+
/* Collect and compile segments we're keeping into a multipolygon */
|
|
1763
|
+
const ringsOut = RingOut.factory(sweepLine.segments);
|
|
1764
|
+
const result = new MultiPolyOut(ringsOut);
|
|
1765
|
+
return result.getGeom();
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1784
1768
|
|
|
1785
|
-
|
|
1769
|
+
// singleton available by import
|
|
1770
|
+
const operation = new Operation();
|
|
1786
1771
|
|
|
1787
|
-
|
|
1772
|
+
const union = function (geom) {
|
|
1788
1773
|
for (var _len = arguments.length, moreGeoms = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
1789
1774
|
moreGeoms[_key - 1] = arguments[_key];
|
|
1790
1775
|
}
|
|
1791
|
-
|
|
1792
|
-
return operation.run('union', geom, moreGeoms);
|
|
1776
|
+
return operation.run("union", geom, moreGeoms);
|
|
1793
1777
|
};
|
|
1794
|
-
|
|
1795
|
-
var intersection$1 = function intersection(geom) {
|
|
1778
|
+
const intersection = function (geom) {
|
|
1796
1779
|
for (var _len2 = arguments.length, moreGeoms = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
1797
1780
|
moreGeoms[_key2 - 1] = arguments[_key2];
|
|
1798
1781
|
}
|
|
1799
|
-
|
|
1800
|
-
return operation.run('intersection', geom, moreGeoms);
|
|
1782
|
+
return operation.run("intersection", geom, moreGeoms);
|
|
1801
1783
|
};
|
|
1802
|
-
|
|
1803
|
-
var xor = function xor(geom) {
|
|
1784
|
+
const xor = function (geom) {
|
|
1804
1785
|
for (var _len3 = arguments.length, moreGeoms = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
1805
1786
|
moreGeoms[_key3 - 1] = arguments[_key3];
|
|
1806
1787
|
}
|
|
1807
|
-
|
|
1808
|
-
return operation.run('xor', geom, moreGeoms);
|
|
1788
|
+
return operation.run("xor", geom, moreGeoms);
|
|
1809
1789
|
};
|
|
1810
|
-
|
|
1811
|
-
var difference = function difference(subjectGeom) {
|
|
1790
|
+
const difference = function (subjectGeom) {
|
|
1812
1791
|
for (var _len4 = arguments.length, clippingGeoms = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
|
|
1813
1792
|
clippingGeoms[_key4 - 1] = arguments[_key4];
|
|
1814
1793
|
}
|
|
1815
|
-
|
|
1816
|
-
return operation.run('difference', subjectGeom, clippingGeoms);
|
|
1794
|
+
return operation.run("difference", subjectGeom, clippingGeoms);
|
|
1817
1795
|
};
|
|
1818
|
-
|
|
1819
1796
|
var index = {
|
|
1820
1797
|
union: union,
|
|
1821
|
-
intersection: intersection
|
|
1798
|
+
intersection: intersection,
|
|
1822
1799
|
xor: xor,
|
|
1823
1800
|
difference: difference
|
|
1824
1801
|
};
|