bufferMultiPolygon.mjs

import get from 'lodash-es/get.js'
import isnum from 'wsemi/src/isnum.mjs'
import isearr from 'wsemi/src/isearr.mjs'
import isestr from 'wsemi/src/isestr.mjs'
import cdbl from 'wsemi/src/cdbl.mjs'
import turf from './importTurf.mjs'
import fixCloseMultiPolygon from './fixCloseMultiPolygon.mjs'
import distilMultiPolygon from './distilMultiPolygon.mjs'


/**
 * 針對MultiPolygon進行Buffer處理
 *
 * Unit Test: {@link https://github.com/yuda-lyu/w-gis/blob/master/test/bufferMultiPolygon.test.mjs Github}
 * @memberOf w-gis
 * @param {Array} pgs 輸入MultiPolygon資料陣列,為[[ [[x11,y11],[x12,y12],...], [[x21,y21],[x22,y22],...] ]]構成之陣列
 * @param {Number} w 輸入Buffer寬度數字
 * @param {Object} [opt={}] 輸入設定物件,預設{}
 * @param {String} [opt.supposeType='polygons'] 輸入提取模式字串,當數據座標深度為2時,使用polygons代表每個其內多邊形為獨立polygon,若為ringStrings則表示其內多邊形為交錯的ringString(代表聯集與剔除),預設'polygons'
 * @param {String} [opt.units='degrees'] 輸入Buffer寬度單位,可選'degrees'、'radians'、'meters'、'kilometers'、'feet'、'miles',預設'degrees'
 * @returns {Array} 回傳MultiPolygon陣列
 * @example
 *
 * let pgs
 * let r
 *
 * pgs = [ //ringString
 *     [0, 0],
 *     [100, 0],
 *     [100, 1],
 *     [0, 1],
 *     [0, 0], //閉合
 * ]
 * r = bufferMultiPolygon(pgs, 1)
 * console.log(JSON.stringify(r))
 * // => [[[[-0.999972965374907, 0.0016734646215225838], [-0.9816999365134195, -0.16952408506808617], [-0.9256550485311431, -0.33424464732165526], [-0.8339576843969376, -0.48618630154023834], [-0.7100824785045414, -0.6195134735411201], [-0.5587377945819172, -0.7290740927297131], [-0.3856985719274389, -0.8105963097699821], [-0.19759749454066486, -0.8608576036547885], [-0.0016801581736105632, -0.8778191418707327], [100.0016801581736, -0.8778191418707327], [100.19759749454067, -0.8608576036547885], [100.38569857192745, -0.8105963097699821], [100.55873779458192, -0.7290740927297131], [100.71008247850455, -0.6195134735411201], [100.83395768439694, -0.48618630154023795], [100.92565504853114, -0.33424464732165526], [100.98169993651341, -0.16952408506808608], [100.99997296537491, 0.0016734646215225838], [101.0001378195948, 0.9962737353793626], [100.98227733151975, 1.1658759961268101], [100.92734305241007, 1.329269548373683], [100.83736709792183, 1.480321394964545], [100.71568951389246, 1.6133389494598158], [100.5668443075726, 1.7232781856005774], [100.39640190540993, 1.8059329159519186], [100.21077163081944, 1.8580983786377043], [100.01696944720078, 1.8777023240108164], [-0.016969447200789016, 1.8777023240108164], [-0.21077163081944233, 1.8580983786377043], [-0.3964019054099387, 1.8059329159519186], [-0.5668443075725933, 1.7232781856005777], [-0.7156895138924567, 1.613338949459816], [-0.8373670979218306, 1.480321394964545], [-0.9273430524100664, 1.3292695483736832], [-0.9822773315197597, 1.1658759961268104], [-1.0001378195948039, 0.9962737353793626], [-0.999972965374907, 0.0016734646215225838]]]]
 *
 * pgs = [ //ringString
 *     [0, 0],
 *     [100, 0],
 *     [100, 1],
 *     [0, 1],
 * ]
 * r = bufferMultiPolygon(pgs, 1)
 * console.log(JSON.stringify(r))
 * // => [[[[-0.999972965374907, 0.0016734646215225838], [-0.9816999365134195, -0.16952408506808617], [-0.9256550485311431, -0.33424464732165526], [-0.8339576843969376, -0.48618630154023834], [-0.7100824785045414, -0.6195134735411201], [-0.5587377945819172, -0.7290740927297131], [-0.3856985719274389, -0.8105963097699821], [-0.19759749454066486, -0.8608576036547885], [-0.0016801581736105632, -0.8778191418707327], [100.0016801581736, -0.8778191418707327], [100.19759749454067, -0.8608576036547885], [100.38569857192745, -0.8105963097699821], [100.55873779458192, -0.7290740927297131], [100.71008247850455, -0.6195134735411201], [100.83395768439694, -0.48618630154023795], [100.92565504853114, -0.33424464732165526], [100.98169993651341, -0.16952408506808608], [100.99997296537491, 0.0016734646215225838], [101.0001378195948, 0.9962737353793626], [100.98227733151975, 1.1658759961268101], [100.92734305241007, 1.329269548373683], [100.83736709792183, 1.480321394964545], [100.71568951389246, 1.6133389494598158], [100.5668443075726, 1.7232781856005774], [100.39640190540993, 1.8059329159519186], [100.21077163081944, 1.8580983786377043], [100.01696944720078, 1.8777023240108164], [-0.016969447200789016, 1.8777023240108164], [-0.21077163081944233, 1.8580983786377043], [-0.3964019054099387, 1.8059329159519186], [-0.5668443075725933, 1.7232781856005777], [-0.7156895138924567, 1.613338949459816], [-0.8373670979218306, 1.480321394964545], [-0.9273430524100664, 1.3292695483736832], [-0.9822773315197597, 1.1658759961268104], [-1.0001378195948039, 0.9962737353793626], [-0.999972965374907, 0.0016734646215225838]]]]
 *
 * pgs = [ //polygon
 *     [
 *         [0, 0],
 *         [100, 0],
 *         [100, 1],
 *         [0, 1],
 *     ]
 * ]
 * r = bufferMultiPolygon(pgs, 1)
 * console.log(JSON.stringify(r))
 * // => [[[[-0.999972965374907, 0.0016734646215225838], [-0.9816999365134195, -0.16952408506808617], [-0.9256550485311431, -0.33424464732165526], [-0.8339576843969376, -0.48618630154023834], [-0.7100824785045414, -0.6195134735411201], [-0.5587377945819172, -0.7290740927297131], [-0.3856985719274389, -0.8105963097699821], [-0.19759749454066486, -0.8608576036547885], [-0.0016801581736105632, -0.8778191418707327], [100.0016801581736, -0.8778191418707327], [100.19759749454067, -0.8608576036547885], [100.38569857192745, -0.8105963097699821], [100.55873779458192, -0.7290740927297131], [100.71008247850455, -0.6195134735411201], [100.83395768439694, -0.48618630154023795], [100.92565504853114, -0.33424464732165526], [100.98169993651341, -0.16952408506808608], [100.99997296537491, 0.0016734646215225838], [101.0001378195948, 0.9962737353793626], [100.98227733151975, 1.1658759961268101], [100.92734305241007, 1.329269548373683], [100.83736709792183, 1.480321394964545], [100.71568951389246, 1.6133389494598158], [100.5668443075726, 1.7232781856005774], [100.39640190540993, 1.8059329159519186], [100.21077163081944, 1.8580983786377043], [100.01696944720078, 1.8777023240108164], [-0.016969447200789016, 1.8777023240108164], [-0.21077163081944233, 1.8580983786377043], [-0.3964019054099387, 1.8059329159519186], [-0.5668443075725933, 1.7232781856005777], [-0.7156895138924567, 1.613338949459816], [-0.8373670979218306, 1.480321394964545], [-0.9273430524100664, 1.3292695483736832], [-0.9822773315197597, 1.1658759961268104], [-1.0001378195948039, 0.9962737353793626], [-0.999972965374907, 0.0016734646215225838]]]]
 *
 * pgs = [ //polygon
 *     [
 *         [0, 0],
 *         [10, 0],
 *         [10, 1],
 *         [0, 1],
 *     ]
 * ]
 * r = bufferMultiPolygon(pgs, 1)
 * console.log(JSON.stringify(r))
 * // => [[[[-0.9999871734419754, 0.00020200853748591523], [-0.9808664898611782, -0.1946303469545636], [-0.9240590295626437, -0.3819873726126987], [-0.8317412783820994, -0.5546734807953713], [-0.7074512829437212, -0.7060534506846929], [-0.5559553546711901, -0.8303064908026484], [-0.38306768046047435, -0.9226499871568967], [-0.195429088113392, -0.9795242908122764], [-0.00025297819980798976, -0.9987311926308354], [10.000252978199807, -0.9987311926308354], [10.195429088113391, -0.9795242908122764], [10.383067680460474, -0.9226499871568967], [10.55595535467119, -0.8303064908026482], [10.70745128294372, -0.7060534506846932], [10.831741278382099, -0.5546734807953713], [10.924059029562644, -0.38198737261269833], [10.980866489861178, -0.19463034695456283], [10.999987173441975, 0.00020200853748591523], [11.000139599094679, 0.9996433568427817], [10.981111268878019, 1.194295116728359], [10.924452966177004, 1.3815039238779527], [10.832325648018566, 1.5540919010292005], [10.70824947011501, 1.7054376090190566], [10.5569720003843, 1.8297295150398156], [10.384289098273342, 1.9221894529124708], [10.196824616632652, 1.9792573819173556], [10.001776914642905, 1.998730032258952], [-0.0017769146429057866, 1.998730032258952], [-0.1968246166326525, 1.9792573819173556], [-0.38428909827334173, 1.9221894529124712], [-0.5569720003843, 1.8297295150398156], [-0.7082494701150103, 1.7054376090190564], [-0.832325648018567, 1.5540919010292005], [-0.9244529661770031, 1.3815039238779527], [-0.9811112688780195, 1.1942951167283595], [-1.0001395990946789, 0.9996433568427817], [-0.9999871734419754, 0.00020200853748591523]]]]
 *
 * pgs = [ //polygon
 *     [
 *         [0, 0],
 *         [100, 0],
 *         [100, 1],
 *         [0, 1],
 *     ],
 *     [
 *         [0, 0],
 *         [10, 0],
 *         [10, 1],
 *         [0, 1],
 *     ]
 * ]
 * r = bufferMultiPolygon(pgs, 1)
 * console.log(JSON.stringify(r))
 * // => [[[[-0.999972965374907, 0.0016734646215225838], [-0.9818179034627895, -0.16898994746760032], [-0.9817286766212256, -0.1692522720975529], [-0.9816999365134195, -0.16952408506808617], [-0.9631011593561465, -0.22407383768307954], [-0.9261241214554894, -0.3332373958589337], [-0.9258324936825051, -0.33372149935647244], [-0.9256550485311431, -0.33424464732165526], [-0.8892908142480597, -0.39442877141272903], [-0.8349844591540967, -0.4848246738151669], [-0.8343937467699749, -0.4854623435574076], [-0.8339576843969376, -0.48618630154023834], [-0.7815123236794599, -0.5425846069291526], [-0.7118306192672567, -0.617966664323285], [-0.7108683890212548, -0.6186663371142785], [-0.7100824785045414, -0.6195134735411201], [-0.6438607603336002, -0.6674180415864824], [-0.5613139162097582, -0.7275512283974191], [-0.5599384315738856, -0.7282038378223106], [-0.5587377945819172, -0.7290740927297131], [-0.4815608678259665, -0.7654105089476456], [-0.38914121973710103, -0.8093331046820568], [-0.38734618924505493, -0.8098192008360738], [-0.3856985719274389, -0.8105963097699821], [-0.300793362822793, -0.8332697929762293], [-0.20186994365286973, -0.8601008071059514], [-0.19968724762839168, -0.8602986156555108], [-0.19759749454066486, -0.8608576036547885], [-0.10847270367557475, -0.868569161366415], [-0.006667604417683045, -0.8778095371878784], [9.993428809235239, -0.9207122196111148], [10.188576797568265, -0.9039018060848659], [10.295049619580887, -0.8747058746123754], [100.0016801581736, -0.8778191418707327], [100.19759749454067, -0.8608576036547885], [100.38569857192745, -0.8105963097699821], [100.55873779458192, -0.7290740927297131], [100.71008247850455, -0.6195134735411201], [100.83395768439694, -0.48618630154023795], [100.92565504853114, -0.33424464732165526], [100.98169993651341, -0.16952408506808608], [100.99997296537491, 0.0016734646215225838], [101.0001378195948, 0.9962737353793626], [100.98227733151975, 1.1658759961268101], [100.92734305241007, 1.329269548373683], [100.83736709792183, 1.480321394964545], [100.71568951389246, 1.6133389494598158], [100.5668443075726, 1.7232781856005774], [100.39640190540993, 1.8059329159519186], [100.21077163081944, 1.8580983786377043], [100.01696944720078, 1.8777023240108164], [-0.016969447200789016, 1.8777023240108164], [-0.11558040549931292, 1.8677241551728063], [-0.20196072981722304, 1.8597293891562097], [-0.20626195777391565, 1.858554257348017], [-0.21077163081944233, 1.8580983786377043], [-0.3067863154675664, 1.8311044071431357], [-0.3893099761639009, 1.8085904175573915], [-0.3926991135614241, 1.806972518540605], [-0.3964019054099387, 1.8059329159519186], [-0.4863105507139498, 1.7623108430118768], [-0.5615422029114501, 1.7264550095794515], [-0.5640106294673816, 1.7246509402885304], [-0.5668443075725933, 1.7232781856005777], [-0.6473490514031758, 1.663783711980742], [-0.7120942637611076, 1.6165517199956638], [-0.7137092988448768, 1.6147998465280684], [-0.7156895138924567, 1.613338949459816], [-0.7838266159960944, 1.5388048864692472], [-0.8352568321155254, 1.4831421001822067], [-0.8361525232284192, 1.4816472873608162], [-0.8373670979218306, 1.480321394964545], [-0.8906132011432863, 1.3908626928796188], [-0.9263796499859861, 1.3313525673628122], [-0.9267439007849886, 1.330273516904206], [-0.9273430524100664, 1.3292695483736832], [-0.9636915808353507, 1.221044761788726], [-0.9820353170742947, 1.1669793617516468], [-0.9820941733833396, 1.1664191164939568], [-0.9822773315197597, 1.1658759961268104], [-1.0001378195948039, 0.9962737353793626], [-0.999972965374907, 0.0016734646215225838]]]]
 *
 * pgs = [ //polygon
 *     [
 *         [0, 0],
 *         [100, 0],
 *         [100, 1],
 *         [0, 1],
 *     ],
 *     [
 *         [0, 0],
 *         [10, 0],
 *         [10, 1],
 *         [0, 1],
 *     ]
 * ]
 * r = bufferMultiPolygon(pgs, 1, { supposeType: 'ringStrings' })
 * console.log(JSON.stringify(r))
 * // => [[[[-0.999972965374907, 0.0016734646215225838], [-0.9816999365134195, -0.16952408506808617], [-0.9256550485311431, -0.33424464732165526], [-0.8339576843969376, -0.48618630154023834], [-0.7100824785045414, -0.6195134735411201], [-0.5587377945819172, -0.7290740927297131], [-0.3856985719274389, -0.8105963097699821], [-0.19759749454066486, -0.8608576036547885], [-0.0016801581736105632, -0.8778191418707327], [100.0016801581736, -0.8778191418707327], [100.19759749454067, -0.8608576036547885], [100.38569857192745, -0.8105963097699821], [100.55873779458192, -0.7290740927297131], [100.71008247850455, -0.6195134735411201], [100.83395768439694, -0.48618630154023795], [100.92565504853114, -0.33424464732165526], [100.98169993651341, -0.16952408506808608], [100.99997296537491, 0.0016734646215225838], [101.0001378195948, 0.9962737353793626], [100.98227733151975, 1.1658759961268101], [100.92734305241007, 1.329269548373683], [100.83736709792183, 1.480321394964545], [100.71568951389246, 1.6133389494598158], [100.5668443075726, 1.7232781856005774], [100.39640190540993, 1.8059329159519186], [100.21077163081944, 1.8580983786377043], [100.01696944720078, 1.8777023240108164], [-0.016969447200789016, 1.8777023240108164], [-0.21077163081944233, 1.8580983786377043], [-0.3964019054099387, 1.8059329159519186], [-0.5668443075725933, 1.7232781856005777], [-0.7156895138924567, 1.613338949459816], [-0.8373670979218306, 1.480321394964545], [-0.9273430524100664, 1.3292695483736832], [-0.9822773315197597, 1.1658759961268104], [-1.0001378195948039, 0.9962737353793626], [-0.999972965374907, 0.0016734646215225838]]]]
 *
 * pgs = [ //multiPolygon
 *     [
 *         [
 *             [0, 0],
 *             [100, 0],
 *             [100, 1],
 *             [0, 1],
 *         ],
 *         [
 *             [0, 0],
 *             [10, 0],
 *             [10, 1],
 *             [0, 1],
 *         ],
 *         [
 *             [0, 0],
 *             [-10, 0],
 *             [-10, 123],
 *             [0, 1],
 *         ]
 *     ]
 * ]
 * r = bufferMultiPolygon(pgs, 1)
 * console.log(JSON.stringify(r))
 * // => [[[[-0.8003200115692618, -0.17319483904229072], [-0.7836767917581119, -0.36185129662050025], [-0.7353492500966056, -0.5356205533066913], [-0.6573598915218491, -0.6875171220741705], [-0.5528860710099704, -0.8114615637915055], [-0.42613263014680774, -0.9025083033202159], [-0.2821710575596541, -0.9570287022736291], [-0.12674982173334867, -0.9728448294506357], [0.03391918073616935, -0.9493106435389045], [0.19339258801976364, -0.8873384160857741], [0.3452397121045475, -0.7893692808009591], [1.5369003654533981, 0.1356647138214438], [9.191588198819693, 0.06826918146634159], [9.192307047783357, -0.13578991039784927], [9.202271009169792, -0.13405428491048416], [10.158804482559859, 0.9689919195461543], [10.16077733912813, 0.9811061542316537], [2.863436899967487, 1.136386159346504], [99.68496688680972, -0.7769642896931913], [99.83421179074095, -0.8734562808152566], [99.98972082173093, -0.9357358967318228], [100.14543660096865, -0.9614370794615064], [100.29533052474301, -0.9495976354600516], [100.43362308806415, -0.9006892544922344], [100.55499140621131, -0.8165981549358158], [100.65475869385061, -0.7005572523974315], [100.72906125012604, -0.5570315931071955], [100.77498905365053, -0.3915596835725485], [100.79069637974868, -0.21055438124997924], [100.7957087779399, 0.7861023638526387], [100.7827532046974, 0.9688299225352316], [100.74119174958985, 1.1529088665478575], [100.67241992924023, 1.3315795752497988], [100.57883417333557, 1.4982369383506398], [100.46376327137136, 1.6466785725630189], [100.33136278849213, 1.7713440655763257], [-0.3606934449687615, 1.7836997442899267], [-0.48814185554933515, 1.6628590462504012], [-0.5984756368305508, 1.5191268524795047], [-0.6879472419221372, 1.357557344702564], [-0.7535627612906908, 1.1837977633730536], [-0.7816588585154715, 1.0561406499162043], [-0.7838663526582138, 1.0453979454196165], [-0.7840227537259681, 1.0454085103112076], [-0.7931718682275202, 1.0038836582061355], [-0.7935555351828718, 0.9982639340509075], [-0.7947986623768644, 0.9922187506328833], [-0.8055260197997868, 0.8240253238448642], [-0.8003200115692618, -0.17319483904229072]]]]
 *
 */
function bufferMultiPolygon(pgs, w, opt = {}) {

    //check pgs
    if (!isearr(pgs)) {
        throw new Error(`no pgs`)
    }

    //check w
    if (!isnum(w)) {
        throw new Error(`invalid w[${w}]`)
    }
    w = cdbl(w)

    //supposeType
    let supposeType = get(opt, 'supposeType')
    if (supposeType !== 'polygons' && supposeType !== 'ringStrings') {
        supposeType = 'polygons'
    }

    //units
    let units = get(opt, 'units', '')
    if (!isestr(units)) {
        units = 'degrees'
    }

    //fixCloseMultiPolygon裡面已有toMultiPolygon故不用另外呼叫處理

    //fixCloseMultiPolygon
    pgs = fixCloseMultiPolygon(pgs, { supposeType })
    // console.log('fixCloseMultiPolygon pgs', JSON.stringify(pgs))

    //multiPolygon
    pgs = turf.multiPolygon(pgs)

    //buffer
    let r = turf.buffer(pgs, w, { units })

    return distilMultiPolygon(r)
}


export default bufferMultiPolygon