1 /***********************************************************************
2  * Copyright (c) 2013-2024 Commonwealth Computer Research, Inc.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Apache License, Version 2.0
5  * which accompanies this distribution and is available at
6  * http://www.opensource.org/licenses/apache2.0.php.
7  ***********************************************************************/
8 
9 package org.locationtech.geomesa.utils.geohash
10 
11 import com.typesafe.scalalogging.LazyLogging
12 import org.locationtech.geomesa.utils.geotools.GeometryUtils
13 import org.locationtech.geomesa.utils.iterators.CartesianProductIterable
14 import org.locationtech.geomesa.utils.text.WKTUtils
15 import org.locationtech.jts.geom._
16 import org.locationtech.spatial4j.context.jts.JtsSpatialContext
17 
18 import scala.collection.BitSet
19 import scala.collection.immutable.HashSet
20 import scala.collection.immutable.Range.Inclusive
21 import scala.util.Try
22 import scala.util.control.Exception.catching
23 
24 /**
25  * The following bits of code are related to common operations involving
26  * GeoHashes, such as recommending a GeoHash precision for an enclosing
27  * polygon; decomposing a polygon into a fixed number of subordinate
28  * GeoHashes; enumerating possible sub-strings within subordinate GeoHashes
29  * for a given polygon; etc.
30  */
31 object GeohashUtils
32   extends GeomDistance
33   with LazyLogging {
34 
35   // make sure the implicits related to distance are in-scope
36   import org.locationtech.geomesa.utils.geotools.Conversions.RichGeometry
37 
38   // these three constants are used in identifying unique GeoHash sub-strings
39   val Base32Padding = (0 to 7).map(i => List.fill(i)(GeoHash.base32.toSeq))
40   val BinaryPadding = (0 to 4).map(i => List.fill(i)(Seq('0', '1')))
41 
42   /**
43    * Simple place-holder for a pair of resolutions, minimum and maximum, along
44    * with an increment.
45    *
46    * @param minBitsResolution minimum number of bits (GeoHash) resolution to consider; must be ODD
47    * @param maxBitsResolution maximum number of bits (GeoHash) resolution to consider; must be ODD
48    */
49   case class ResolutionRange(minBitsResolution:Int=5,
50                              maxBitsResolution:Int=63,
51                              numBitsIncrement:Int=2) {
52     // validate resolution arguments
53     if (minBitsResolution >= maxBitsResolution)
54       throw new IllegalArgumentException("Minimum resolution must be strictly greater than maximum resolution.")
55 
56     lazy val range: Range = new Inclusive(minBitsResolution, maxBitsResolution, numBitsIncrement)
57     override def toString(): String = "{" + minBitsResolution.toString + ", +" + numBitsIncrement + "..., " + maxBitsResolution.toString + "}"
58 
59     def getNumChildren: Int = 1 << numBitsIncrement
60 
61     def getNextChildren(parent:BitSet, oldPrecision:Int) : List[BitSet] =
62       Range(0, getNumChildren).map { i =>
63         // compute bit-set corresponding to this integer,
64         // and add it to the left-shifted version of the parent
65         val bitString = i.toBinaryString
66 
67         Range(0, numBitsIncrement).foldLeft(parent) { case (bs, j) =>
68           val c = if (j < bitString.length) bitString.charAt(j) else '0'
69           if (c == '1') bs + (oldPrecision + bitString.length - 1 - j)
70           else bs
71         }
72       }.toList
73 
74   }
75 
76   // default precision model
77   val maxRealisticGeoHashPrecision : Int = 45
78   val numDistinctGridPoints: Long = 1L << ((maxRealisticGeoHashPrecision+1)/2).toLong
79   val defaultPrecisionModel = new PrecisionModel(numDistinctGridPoints.toDouble)
80 
81   // default factory for WGS84
82   val defaultGeometryFactory : GeometryFactory = new GeometryFactory(defaultPrecisionModel, 4326)
83 
84   /**
85    * Utility function that computes the minimum-bounding GeoHash that completely
86    * encloses the given (target) geometry.  This can be useful as a starting
87    * point for other calculations on the geometry.
88    *
89    * This is a bit of a short-cut, because what it *really* does is to start
90    * with the centroid of the target geometry, and step down through resolutions
91    * (in bits) for as long as a GeoHash constructed for that centroid continues
92    * to enclose the entire geometry.  This works, because any GeoHash that
93    * encloses the entire geometry must also include the centroid (as well as
94    * any other point).
95    *
96    * @param geom the target geometry that is to be enclosed
97    * @return the smallest GeoHash -- at an odd number of bits resolution -- that
98    *         completely encloses the target geometry
99    */
100   def getMinimumBoundingGeohash(geom:Geometry, resolutions:ResolutionRange) : GeoHash = {
101     // save yourself some effort by computing the geometry's centroid and envelope up front
102     val centroid = getCentroid(geom)
103     val env = defaultGeometryFactory.toGeometry(geom.getEnvelopeInternal)
104 
105     // conduct the search through the various candidate resolutions
106     val (_, ghOpt) = resolutions.range.foldRight((resolutions.minBitsResolution, Option.empty[GeoHash])){
107       case (bits, orig@(res, _)) =>
108         val gh = GeoHash(centroid.getX, centroid.getY, bits)
109         if (gh.contains(env) && bits >= res) (bits, Some(gh)) else orig
110     }
111 
112     // validate that you found a usable result
113     val gh = ghOpt.getOrElse(GeoHash(centroid.getX, centroid.getY, resolutions.minBitsResolution))
114     if (!gh.contains(env) && !gh.geom.equals(env))
115       throw new Exception("ERROR:  Could not find a suitable " +
116         resolutions.minBitsResolution + "-bit MBR for the target geometry:  " +
117         geom)
118 
119     gh
120   }
121 
122   /**
123    * Computes the centroid of the given geometry as a WGS84 point.
124    *
125    * @param geom the target geometry whose centroid is sought
126    * @return the centroid of the given geometry
127    */
128   def getCentroid(geom:Geometry) : Point = {
129     val pt = geom.safeCentroid()
130     geom.getFactory.createPoint(new Coordinate(pt.getX, pt.getY))
131   }
132 
133   // represents a degenerate (empty) geometry
134   lazy val emptyGeometry: Geometry = WKTUtils.read("POLYGON((0 0,0 0,0 0,0 0,0 0))")
135 
136   /**
137    * Utility class for the geometry-decomposition routines.  This represents
138    * one GeoHash-cell candidate within a decomposition.
139    *
140    * @param gh the associated GeoHash cell
141    * @param targetGeom the geometry being decomposed
142    */
143   abstract class DecompositionCandidate(val gh:GeoHash,
144                                         val targetGeom:Geometry,
145                                         val targetArea:Double,
146                                         val resolutions:ResolutionRange) {
147 
148     lazy val geomCatcher = catching(classOf[Exception])
149     lazy val area: Double = geomCatcher.opt{ gh.getArea }.getOrElse(0.0)
150     val areaOutside: Double
151     lazy val areaInside: Double = area - areaOutside
152     lazy val resolution: Int = gh.prec
153     lazy val isResolutionOk: Boolean =
154       resolution >= resolutions.minBitsResolution && resolution <= resolutions.maxBitsResolution
155 
156     lazy val intersectsTarget: Boolean =
157       geomCatcher.opt { gh.intersects(targetGeom) }.getOrElse(false)
158     lazy val intersection: Geometry =
159       geomCatcher.opt { gh.intersection(targetGeom) }.getOrElse(emptyGeometry)
160     lazy val intersectionArea: Double =
161       geomCatcher.opt { gh.intersection(targetGeom).getArea }.getOrElse(0.0)
162     def isLT(than:DecompositionCandidate): Boolean = {
163       if (areaOutside > than.areaOutside) true
164       else {
165         if (areaOutside == than.areaOutside) area < than.area
166         else false
167       }
168     }
169   }
170 
171   class PointDecompositionCandidate(gh:GeoHash,
172                                     targetGeom:Point,
173                                     targetArea:Double,
174                                     resolutions:ResolutionRange)
175     extends DecompositionCandidate(gh, targetGeom, targetArea, resolutions) {
176 
177     /**
178      * If the GeoHash does not contain the point, then the entire cell's area is
179      * outside of the target.  If the GeoHash does contain the point, then be
180      * careful:  Only some fraction of the cell's area should count as overage
181      * (otherwise, we can't favor smaller GeoHash cells in the decomposer).
182      */
183     override lazy val areaOutside: Double = area * (if (intersectsTarget) 0.75 else 1.0)
184   }
185 
186   class LineDecompositionCandidate(gh:GeoHash,
187                                    targetGeom:MultiLineString,
188                                    targetArea:Double,
189                                    resolutions:ResolutionRange)
190     extends DecompositionCandidate(gh, targetGeom, targetArea, resolutions) {
191 
192     /**
193      * If the GeoHash intersects the target lines, then the overlap is the
194      * area of the GeoHash cell less the length of the intersection.  Otherwise,
195      * they are disjoint, and the overlap is the entire area of the GeoHash cell.
196      *
197      * Yes, this mixes units, but it observes two trends:
198      * 1.  the longer a segment intersects, the smaller the area outside will be;
199      * 2.  the smaller a GeoHash cell, the smaller the area outside will be
200      */
201     override lazy val areaOutside : Double =
202       if (intersectsTarget) area * (1.0 - intersection.getLength / targetArea)
203       else area
204   }
205 
206   class PolygonDecompositionCandidate(gh:GeoHash,
207                                       targetGeom:MultiPolygon,
208                                       targetArea:Double,
209                                       resolutions:ResolutionRange)
210     extends DecompositionCandidate(gh, targetGeom, targetArea, resolutions) {
211 
212     /**
213      * If the GeoHash intersects the target polygon, then the overlap is the
214      * area of the GeoHash cell less the area of the intersection.  Otherwise,
215      * they are disjoint, and the overlap is the entire area of the GeoHash cell.
216      */
217     override lazy val areaOutside : Double =
218       if (intersectsTarget) area - intersection.getArea
219       else area
220   }
221 
222   def decompositionCandidateSorter(a:DecompositionCandidate,
223                                    b:DecompositionCandidate): Boolean = a.isLT(b)
224 
225   /**
226    * Decomposes the given polygon into a collection of disjoint GeoHash cells
227    * so that these constraints are satisfied:
228    * 1.  the total number of decomposed GeoHashes does not exceed the maximum
229    *     specified as an argument
230    * 2.  the resolution of the GeoHashes falls within the given range
231    * 3.  when replacing larger boxes with smaller boxes, always decompose first
232    *     the box that contains the most area outside the target polygon
233    *
234    * @param targetGeom the polygon to be decomposed
235    * @param maxSize the maximum number of GeoHash cells into which this polygon
236    *                should be decomposed
237    * @param resolutions the list of acceptable resolutions for the GeoHash cells
238    * @return the list of GeoHash cells into which this polygon was decomposed
239    *         under the given constraints
240    */
241   private def decomposeGeometry_(targetGeom: Geometry,
242                                  maxSize: Int = 100,
243                                  resolutions: ResolutionRange = new ResolutionRange(5,40,5)): List[GeoHash] = {
244     lazy val geomCatcher = catching(classOf[Exception])
245     val targetArea : Double = geomCatcher.opt { targetGeom.getArea }.getOrElse(0.0)
246     val targetLength : Double = geomCatcher.opt { targetGeom.getLength }.getOrElse(0.0)
247 
248     // qua factory
249     def createDecompositionCandidate(gh: GeoHash): DecompositionCandidate = {
250       // simple switch based on the geometry type
251       targetGeom match {
252         case multipoly: MultiPolygon    =>
253           new PolygonDecompositionCandidate(gh, multipoly, targetArea, resolutions)
254         case polygon: Polygon           =>
255           new PolygonDecompositionCandidate(
256             gh, new MultiPolygon(Array(polygon), polygon.getFactory), targetArea, resolutions)
257         case line: LineString           =>
258           new LineDecompositionCandidate(  // promote to a multi-line string of one element
259             gh, new MultiLineString(Array(line), line.getFactory), targetLength, resolutions)
260         case multiLine: MultiLineString =>
261           new LineDecompositionCandidate(gh, multiLine, targetLength, resolutions)
262         case point: Point               =>
263           new PointDecompositionCandidate(gh, point, targetArea, resolutions)  // should never be called, but it works
264         case _                          =>
265           throw new Exception(s"Unsupported Geometry type for decomposition:  ${targetGeom.getClass.getName}")
266       }
267     }
268 
269     // recursive routine that will do the actual decomposition
270     def decomposeStep(candidates: List[DecompositionCandidate]): List[DecompositionCandidate] = {
271       // complain, if needed
272       if (candidates.size > maxSize) throw new Exception("Too many candidates upon entry.")
273       else {
274         // identify the partial to replace...
275         // which of the single candidates contains the least overlap (area outside the target geometry)?
276         // assume that these are always sorted so that they are in descending order of overlap-area
277         val candidate : DecompositionCandidate = candidates(0)
278         val childResolution : Int = candidate.gh.prec+resolutions.numBitsIncrement
279 
280         // decompose this (worst) candidate into its four children
281         val candidateBitSet : BitSet = candidate.gh.bitset
282         val children:List[DecompositionCandidate] = resolutions.getNextChildren(candidateBitSet, candidate.gh.prec).map((childBitSet) => {
283           createDecompositionCandidate(GeoHash(childBitSet, childResolution))
284         }).filter(child => child.intersectsTarget)
285 
286         // build the next iteration of candidates
287         val newCandidates : List[DecompositionCandidate] = (candidates.tail ++ children).sortWith(decompositionCandidateSorter)
288 
289         // recurse, if appropriate
290         if ((newCandidates.size <= maxSize) && (childResolution <= resolutions.maxBitsResolution)) {
291           decomposeStep(newCandidates)
292         } else candidates
293       }
294     }
295 
296     // identify the smallest GeoHash that contains the entire polygon
297     val ghMBR = getMinimumBoundingGeohash(targetGeom, resolutions)
298     val candidateMBR = createDecompositionCandidate(ghMBR)
299 
300     // recursively decompose worst choices
301     val (keepers:List[DecompositionCandidate]) = decomposeStep(List(candidateMBR))
302 
303     // return only the keepers
304     (for (keeper:DecompositionCandidate <- keepers) yield keeper.gh).toList
305   }
306 
307   def getDecomposableGeometry(targetGeom: Geometry): Geometry = targetGeom match {
308     case g: Point                                            => targetGeom
309     case g: Polygon                                          => targetGeom
310     case g: LineString      if targetGeom.getNumPoints < 100 => targetGeom
311     case g: MultiLineString if targetGeom.getNumPoints < 100 => targetGeom
312     case _                                                   => targetGeom.convexHull
313   }
314 
315   /**
316    * Transforms a geometry with lon in (-inf, inf) and lat in [-90,90] to a geometry in whole earth BBOX
317    * 1) any coords of geometry outside lon [-180,180] are transformed to be within [-180,180]
318    *    (to avoid spatial4j validation errors)
319    * 2) use spatial4j to create a geometry with inferred International Date Line crossings
320    *    (if successive coordinates longitudinal difference is greater than 180)
321    * Parts of geometries with lat outside [-90,90] are ignored.
322    * To represent a geometry with successive coordinates having lon diff > 180 and not wrapping
323    * the IDL, you must insert a waypoint such that the difference is less than 180
324    */
325   def getInternationalDateLineSafeGeometry(targetGeom: Geometry): Try[Geometry] = {
326 
327     def degreesLonTranslation(lon: Double): Double = (((lon + 180) / 360.0).floor * -360).toInt
328 
329     def translateCoord(coord: Coordinate): Coordinate = {
330       new Coordinate(coord.x + degreesLonTranslation(coord.x), coord.y)
331     }
332 
333     def translatePolygon(geometry: Geometry): Geometry =
334       defaultGeometryFactory.createPolygon(geometry.getCoordinates.map(c => translateCoord(c)))
335 
336     def translateLineString(geometry: Geometry): Geometry =
337       defaultGeometryFactory.createLineString(geometry.getCoordinates.map(c => translateCoord(c)))
338 
339     def translateMultiLineString(geometry: Geometry): Geometry = {
340       val coords = (0 until geometry.getNumGeometries).map { i => geometry.getGeometryN(i) }
341       val translated = coords.map { c => translateLineString(c).asInstanceOf[LineString] }
342       defaultGeometryFactory.createMultiLineString(translated.toArray)
343     }
344 
345     def translateMultiPolygon(geometry: Geometry): Geometry = {
346       val coords = (0 until geometry.getNumGeometries).map { i => geometry.getGeometryN(i) }
347       val translated = coords.map { c => translatePolygon(c).asInstanceOf[Polygon] }
348       defaultGeometryFactory.createMultiPolygon(translated.toArray)
349     }
350 
351     def translateMultiPoint(geometry: Geometry): Geometry =
352       defaultGeometryFactory.createMultiPoint(geometry.getCoordinates.map(c => translateCoord(c)))
353 
354     def translatePoint(geometry: Geometry): Geometry = {
355       defaultGeometryFactory.createPoint(translateCoord(geometry.getCoordinate))
356     }
357 
358     def translateGeometry(geometry: Geometry): Geometry = {
359       geometry match {
360         case p: Polygon =>          translatePolygon(geometry)
361         case l: LineString =>       translateLineString(geometry)
362         case m: MultiLineString =>  translateMultiLineString(geometry)
363         case m: MultiPolygon =>     translateMultiPolygon(geometry)
364         case m: MultiPoint =>       translateMultiPoint(geometry)
365         case p: Point =>            translatePoint(geometry)
366       }
367     }
368 
369     Try {
370       // copy the geometry so that we don't modify the input - JTS mutates the geometry
371       // don't use the defaultGeometryFactory as it has limited precision
372       val copy = GeometryUtils.geoFactory.createGeometry(targetGeom)
373       val withinBoundsGeom =
374         if (targetGeom.getEnvelopeInternal.getMinX < -180 || targetGeom.getEnvelopeInternal.getMaxX > 180)
375           translateGeometry(copy)
376         else
377           copy
378 
379       JtsSpatialContext.GEO.makeShape(withinBoundsGeom, true, true).getGeom
380     }
381   }
382 
383   /**
384    * Quick-and-dirty sieve that ensures that we don't waste time decomposing
385    * single points.
386    */
387   def decomposeGeometry(targetGeom: Geometry,
388                         maxSize: Int = 100,
389                         resolutions: ResolutionRange = ResolutionRange(0, 40, 5),
390                         relaxFit: Boolean = true): List[GeoHash] = {
391   // quick hit to avoid wasting time for single points
392     targetGeom match {
393       case point: Point => List(GeoHash(point.getX, point.getY, resolutions.maxBitsResolution))
394       case gc: GeometryCollection => (0 until gc.getNumGeometries).toList.flatMap { i =>
395         decomposeGeometry(gc.getGeometryN(i), maxSize, resolutions, relaxFit)
396       }.distinct
397       case _ =>
398         val safeGeom = getInternationalDateLineSafeGeometry(targetGeom).getOrElse(targetGeom)
399         decomposeGeometry_(
400           if (relaxFit) getDecomposableGeometry(safeGeom)
401           else safeGeom, maxSize, resolutions)
402     }
403   }
404 
405   /**
406    * Given a collection of GeoHash hash sub-strings, this routine
407    * will build an iterator that generates all dotted variants.
408    * "Dotted" in this context means supporting the abstracted
409    * representation (in which higher-level hash-strings use periods
410    * for the base-32 characters they don't use).  For example,
411    * if the string is "dqb", then the dotted variants include all
412    * of the following:
413    *
414    *   dqb
415    *   dq.
416    *   d..
417    *   ...
418    *
419    * @param set the collection of GeoHash hash substrings to dot
420    * @param maxSize the maximum allowable number of entries in the final
421    *                iterator
422    * @return an iterator over the dotted collection of hash substrings,
423    *         constrained to one more than the maximum allowable size
424    *         (to enable overflow-detection on the outside)
425    */
426   def getGeohashStringDottingIterator(set: Seq[String], maxSize: Int): Iterator[String] = {
427     val len = set.headOption.map(_.length).getOrElse(0)
428     (for {
429       i <- (0 to len).iterator
430       hash <- set.map(_.take(i)).distinct
431       newStr = hash.take(i) + "".padTo(len - i, ".").mkString
432     } yield newStr).take(maxSize + 1)
433   }
434 
435   def promoteToRegion(geom: Geometry): Geometry = geom match {
436     case g: Point   =>
437       g.buffer(1e-6)
438     case g: Polygon =>
439       if (g.getArea > 0.0) g
440       else g.safeCentroid().buffer(1e-6)
441     case g          =>
442       val env = g.getEnvelope
443       if (env.getArea > 0.0) env
444       else env.getCentroid.buffer(1e-6)
445   }
446 
447   /**
448    * Given an index-schema format such as "%1,3#gh", it becomes necessary to
449    * identify which unique 3-character GeoHash sub-strings intersect the
450    * query polygon.  This routine performs exactly such an identification.
451    *
452    * The full GeoHashes from which the sub-strings are extracted are computed
453    * at 35 bits.
454    *
455    * Computing all of the 35-bit GeoHashes that intersect with the target
456    * geometry can take too long.  Instead, we start with the minimum-bounding
457    * GeoHash (which might be 0 bits), and recursively dividing it in two
458    * while remembering those GeoHashes that are completely contained in the
459    * target geometry.  This has a few advantages:
460    *
461    * 1.  we can stop recursing into GeoHashes at the coarsest
462    *     level (largest geometry) possible when they stop intersecting
463    *     the target geometry;
464    * 2.  instead of enumerating all of the GeoHashes that intersect, we
465    *     can stop as soon as we know that all possible children are known
466    *     to be inside the target geometry; that is, if a 13-bit GeoHash
467    *     is covered by the target, then we know that all 15-bit GeoHashes
468    *     that are its children will also be covered by the target
469    * 3.  if we ever find a GeoHash that is entirely covered by the target
470    *     geometry whose precision is no more than 5 times the "offset"
471    *     parameter's number of bits, then we can stop, because all possible
472    *     combinations are known to be used
473    *
474    * As an example, consider trying to enumerate the (3, 2) sub-strings of
475    * GeoHashes in a polygon that is only slightly inset within the
476    * Southern hemisphere.  This implicates a large number of 25-bit
477    * GeoHashes, but as soon as one of the GeoHashes that has 15 or fewer
478    * bits is found that is covered by the target, the search can stop
479    * for unique prefixes, because all of its 25-bit children will be
480    * distinct and will also be covered by the target.
481    *
482    * This is easier to explain with pictures.
483    *
484    * @param geom the query-polygon that must intersect candidate GeoHashes
485    * @param offset how many of the left-most GeoHash characters to skip
486    * @param length how many of the (remaining) GeoHash characters to use
487    * @param MAX_KEYS_IN_LIST the maximum allowable number of unique GeoHash
488    *                         sub-strings; when exceeded, the function returns
489    *                         an empty list
490    *
491    * @return the list of unique GeoHash sub-strings from 35-bits precision that
492    *         intersect the target polygon; an empty list if there are too many
493    */
494   def getUniqueGeohashSubstringsInPolygon(geom: Geometry,
495                                           offset: Int,
496                                           length: Int,
497                                           MAX_KEYS_IN_LIST: Int = Int.MaxValue - 1,
498                                           includeDots: Boolean = true): Try[Seq[String]] = Try {
499 
500     val cover = promoteToRegion(geom)
501 
502     //val cover: Geometry = geom.buffer(0)
503     val maxBits = (offset + length) * 5
504     val minBits = offset * 5
505     val usedBits = length * 5
506     val allResolutions = ResolutionRange(0, Math.min(35, maxBits), 1)
507     val maxKeys = Math.min(2 << Math.min(usedBits, 29), MAX_KEYS_IN_LIST)
508     val polyCentroid = cover.safeCentroid()
509 
510     // find the smallest GeoHash you can that covers the target geometry
511     val ghMBR = getMinimumBoundingGeohash(geom, allResolutions)
512 
513     // this case-class closes over properties of the current search
514     case class BitPrefixes(prefixes: Seq[String]) {
515 
516       val hasEverythingPrefix = prefixes.exists(prefix => prefix.length <= minBits)
517 
518       // how many GeoHashes are entailed by the list of prefixes
519       val entailedSize =
520         if (hasEverythingPrefix) maxKeys
521         else Math.min(
522           1 << usedBits,
523           prefixes.foldLeft(0)((sumSoFar, prefix) => {
524             sumSoFar + (1 << Math.min(usedBits, maxBits - prefix.length))
525           }))
526 
527       // is there any prefix wholly contained within the target geometry
528       // that uses fewer than 5*offset bits?  if so, then all possible
529       // sub-strings are entailed
530       val usesAll = prefixes.exists(prefix => prefix.length <= minBits) ||
531         entailedSize == maxKeys
532 
533       // the loose inequality is so that we can detect overflow
534       def hasRoom = entailedSize <= maxKeys
535 
536       def notDone = !usesAll && hasRoom
537 
538       def overflowed =
539         if (usesAll) {
540           (1 << usedBits) > maxKeys
541         } else {
542           entailedSize > maxKeys
543         }
544 
545       // generate all combinations of GeoHash strings of
546       // the desired length
547       def generateAll(prefix: String): Seq[String] = {
548         val prefixHash = GeoHash.fromBinaryString(prefix).hash
549         if (prefixHash.length < length) {
550           val charSeqs = Base32Padding(length - prefixHash.length)
551           CartesianProductIterable(charSeqs).toList.map(prefixHash + _.mkString)
552         } else Seq(prefixHash)
553       }
554 
555       // generate all of the combinations entailed by the prefixes identified,
556       // all of which will have bits that overlap with the requested substring
557       // (that is, if we want (3,2), then all of the prefixes we identified have
558       // somewhere between 15 and 25 bits in them)
559       //
560       // each prefix, then, needs to be expanded to a list of all combinations
561       // of bits that reach the next 5-bit boundary, and then those prefixes
562       // can be expanded to use all combinations of base-32 characters that
563       // allow them to fill out the requisite range
564       def generateSome: Seq[String] = {
565         prefixes.foldLeft(HashSet[String]())((ghsSoFar, prefix) => {
566           // fill out this prefix to the next 5-bit boundary
567           val bitsToBoundary = (65 - prefix.length) % 5
568           val bases =
569             if (bitsToBoundary == 0) Seq(prefix)
570             else {
571               val fillers = BinaryPadding(bitsToBoundary)
572               val result = CartesianProductIterable(fillers).toList.map(prefix + _.mkString)
573               result
574             }
575           bases.foldLeft(ghsSoFar)((ghs, base) => {
576             val baseTrimmed = base.drop(minBits)
577             val newSubs = generateAll(baseTrimmed)
578             ghs ++ newSubs
579           })
580         }).toSeq
581       }
582 
583       def toSeq: Seq[String] =
584         if (usesAll) generateAll("")
585         else generateSome
586     }
587 
588     // assume that this method is never called on a GeoHash
589     // whose binary-string encoding is too long
590     def considerCandidate(candidate: GeoHash): Seq[String] = {
591       val bitString = candidate.toBinaryString
592 
593       if (!geom.intersects(candidate.geom)) return Nil
594 
595       if (cover.covers(candidate.geom) || (bitString.size == maxBits)) {
596         Seq(bitString)
597       } else {
598         if (bitString.size < maxBits) {
599           // choose which direction to recurse into next by proximity
600           // of the two child GeoHashes to the polygon's centroid;
601           // for rectangles or polygons whose area is concentrated
602           // near the centroid, this provides for a a HUGE speed increase
603           val gh0 = GeoHash.fromBinaryString(bitString + "0")
604           val gh1 = GeoHash.fromBinaryString(bitString + "1")
605           val d0 = Math.hypot(gh0.getPoint.getX - polyCentroid.getX, gh0.getPoint.getY - polyCentroid.getY)
606           val d1 = Math.hypot(gh1.getPoint.getX - polyCentroid.getX, gh1.getPoint.getY - polyCentroid.getY)
607           val (firstChild, secondChild) =
608             if (d0 <= d1) (gh0, gh1)
609             else (gh1, gh0)
610 
611           val firstChildList = considerCandidate(firstChild)
612 
613           // if you've found an entry that entails all sub-strings, stop searching
614           firstChildList ++ (firstChildList.headOption match {
615             case Some(bitStr) if bitStr.length <= minBits => Nil
616             case _                                        =>
617               considerCandidate(secondChild)
618           })
619         } else Nil
620       }
621     }
622 
623     // compute the list of acceptable prefixes
624     val bitPrefixes = BitPrefixes(
625       if (ghMBR.prec <= maxBits) considerCandidate(ghMBR)
626       else Seq(ghMBR.toBinaryString.drop(minBits).take(usedBits)))
627 
628     // detect overflow
629     if (bitPrefixes.overflowed) throw new IllegalStateException("Bit prefixes overflowed while calculating unique Geohash substrings in polygon using the following parameters: " +
630       s"\nGeometry: $geom \nOffset: $offset \nLength: $length \nMax Keys in List: $MAX_KEYS_IN_LIST")
631 
632     // not having overflowed, turn the collection of disjoint prefixes
633     // into a list of full geohash substrings
634     val unDotted = bitPrefixes.toSeq
635 
636     // add dotted versions, if appropriate (to match decomposed GeoHashes that
637     // may be encoded at less than a full 35-bits precision)
638     if (includeDots) {
639       if (unDotted.size < maxKeys) {
640         // STOP as soon as you've exceeded the maximum allowable entries
641         val keepers = getGeohashStringDottingIterator(
642           unDotted, MAX_KEYS_IN_LIST).take(MAX_KEYS_IN_LIST + 1).toList
643         if (keepers.size <= MAX_KEYS_IN_LIST) keepers.toSeq else Seq()
644       } else Seq()
645     } else unDotted
646   }
647 }
Line Stmt Id Pos Tree Symbol Tests Code
39 5299 1665 - 1666 Literal <nosymbol> 0
39 5300 1670 - 1671 Literal <nosymbol> 7
39 5301 1695 - 1709 Select org.locationtech.geomesa.utils.geohash.GeoHash.base32 GeoHash.base32
39 5302 1695 - 1715 Select scala.collection.SeqLike.toSeq scala.Predef.augmentString(GeoHash.base32).toSeq
39 5303 1682 - 1716 Apply scala.collection.generic.GenTraversableFactory.fill scala.collection.immutable.List.fill[Seq[Char]](i)(scala.Predef.augmentString(GeoHash.base32).toSeq)
39 5304 1676 - 1676 TypeApply scala.collection.immutable.IndexedSeq.canBuildFrom immutable.this.IndexedSeq.canBuildFrom[List[Seq[Char]]]
39 5305 1664 - 1717 ApplyToImplicitArgs scala.collection.TraversableLike.map scala.Predef.intWrapper(0).to(7).map[List[Seq[Char]], scala.collection.immutable.IndexedSeq[List[Seq[Char]]]](((i: Int) => scala.collection.immutable.List.fill[Seq[Char]](i)(scala.Predef.augmentString(GeoHash.base32).toSeq)))(immutable.this.IndexedSeq.canBuildFrom[List[Seq[Char]]])
40 5306 1741 - 1742 Literal <nosymbol> 0
40 5307 1746 - 1747 Literal <nosymbol> 4
40 5308 1771 - 1784 Apply scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[Char]('0', '1')
40 5309 1758 - 1785 Apply scala.collection.generic.GenTraversableFactory.fill scala.collection.immutable.List.fill[Seq[Char]](i)(scala.collection.Seq.apply[Char]('0', '1'))
40 5310 1752 - 1752 TypeApply scala.collection.immutable.IndexedSeq.canBuildFrom immutable.this.IndexedSeq.canBuildFrom[List[Seq[Char]]]
40 5311 1740 - 1786 ApplyToImplicitArgs scala.collection.TraversableLike.map scala.Predef.intWrapper(0).to(4).map[List[Seq[Char]], scala.collection.immutable.IndexedSeq[List[Seq[Char]]]](((i: Int) => scala.collection.immutable.List.fill[Seq[Char]](i)(scala.collection.Seq.apply[Char]('0', '1'))))(immutable.this.IndexedSeq.canBuildFrom[List[Seq[Char]]])
53 5312 2336 - 2353 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.maxBitsResolution ResolutionRange.this.maxBitsResolution
53 5313 2315 - 2353 Apply scala.Int.>= ResolutionRange.this.minBitsResolution.>=(ResolutionRange.this.maxBitsResolution)
53 5316 2311 - 2311 Literal <nosymbol> ()
53 5317 2311 - 2311 Block <nosymbol> ()
54 5314 2361 - 2467 Throw <nosymbol> throw new scala.`package`.IllegalArgumentException("Minimum resolution must be strictly greater than maximum resolution.")
54 5315 2361 - 2467 Block <nosymbol> throw new scala.`package`.IllegalArgumentException("Minimum resolution must be strictly greater than maximum resolution.")
57 5318 2605 - 2709 Apply java.lang.String.+ "{".+(ResolutionRange.this.minBitsResolution.toString()).+(", +").+(ResolutionRange.this.numBitsIncrement).+("..., ").+(ResolutionRange.this.maxBitsResolution.toString()).+("}")
59 5319 2741 - 2742 Literal <nosymbol> 1
59 5320 2746 - 2762 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.numBitsIncrement ResolutionRange.this.numBitsIncrement
59 5321 2741 - 2762 Apply scala.Int.<< 1.<<(ResolutionRange.this.numBitsIncrement)
62 5322 2850 - 2851 Literal <nosymbol> 0
62 5323 2853 - 2867 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.getNumChildren ResolutionRange.this.getNumChildren
62 5340 2873 - 2873 TypeApply scala.collection.immutable.IndexedSeq.canBuildFrom immutable.this.IndexedSeq.canBuildFrom[scala.collection.BitSet]
65 5324 3026 - 3042 Select scala.runtime.RichInt.toBinaryString scala.Predef.intWrapper(i).toBinaryString
67 5325 3058 - 3059 Literal <nosymbol> 0
67 5326 3061 - 3077 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.numBitsIncrement ResolutionRange.this.numBitsIncrement
67 5338 3111 - 3275 Block <nosymbol> { val c: Char = if (j.<(bitString.length())) bitString.charAt(j) else '0'; if (c.==('1')) bs.+(oldPrecision.+(bitString.length()).-(1).-(j)) else bs }
67 5339 3052 - 3285 Apply scala.collection.TraversableOnce.foldLeft scala.`package`.Range.apply(0, ResolutionRange.this.numBitsIncrement).foldLeft[scala.collection.BitSet](parent)(((x0$1: scala.collection.BitSet, x1$1: Int) => scala.Tuple2.apply[scala.collection.BitSet, Int](x0$1, x1$1) match { case (_1: scala.collection.BitSet, _2: Int)(scala.collection.BitSet, Int)((bs @ _), (j @ _)) => { val c: Char = if (j.<(bitString.length())) bitString.charAt(j) else '0'; if (c.==('1')) bs.+(oldPrecision.+(bitString.length()).-(1).-(j)) else bs } }))
68 5327 3140 - 3156 Apply java.lang.String.length bitString.length()
68 5328 3136 - 3156 Apply scala.Int.< j.<(bitString.length())
68 5329 3158 - 3177 Apply java.lang.String.charAt bitString.charAt(j)
68 5330 3158 - 3177 Block java.lang.String.charAt bitString.charAt(j)
68 5331 3183 - 3186 Literal <nosymbol> '0'
68 5332 3183 - 3186 Block <nosymbol> '0'
69 5333 3201 - 3209 Apply scala.Char.== c.==('1')
69 5334 3217 - 3256 Apply scala.Int.- oldPrecision.+(bitString.length()).-(1).-(j)
69 5335 3211 - 3257 Apply scala.collection.SetLike.+ bs.+(oldPrecision.+(bitString.length()).-(1).-(j))
69 5336 3211 - 3257 Block scala.collection.SetLike.+ bs.+(oldPrecision.+(bitString.length()).-(1).-(j))
70 5337 3273 - 3275 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.bs bs
72 5341 2844 - 3300 Select scala.collection.TraversableOnce.toList scala.`package`.Range.apply(0, ResolutionRange.this.getNumChildren).map[scala.collection.BitSet, scala.collection.immutable.IndexedSeq[scala.collection.BitSet]](((i: Int) => { val bitString: String = scala.Predef.intWrapper(i).toBinaryString; scala.`package`.Range.apply(0, ResolutionRange.this.numBitsIncrement).foldLeft[scala.collection.BitSet](parent)(((x0$1: scala.collection.BitSet, x1$1: Int) => scala.Tuple2.apply[scala.collection.BitSet, Int](x0$1, x1$1) match { case (_1: scala.collection.BitSet, _2: Int)(scala.collection.BitSet, Int)((bs @ _), (j @ _)) => { val c: Char = if (j.<(bitString.length())) bitString.charAt(j) else '0'; if (c.==('1')) bs.+(oldPrecision.+(bitString.length()).-(1).-(j)) else bs } })) }))(immutable.this.IndexedSeq.canBuildFrom[scala.collection.BitSet]).toList
77 5342 3379 - 3381 Literal <nosymbol> 45
78 5343 3418 - 3420 Literal <nosymbol> 1L
78 5344 3455 - 3456 Literal <nosymbol> 1
78 5345 3458 - 3459 Literal <nosymbol> 2
78 5346 3424 - 3467 Select scala.Int.toLong GeohashUtils.this.maxRealisticGeoHashPrecision.+(1)./(2).toLong
78 5347 3418 - 3467 Apply scala.Long.<< 1L.<<(GeohashUtils.this.maxRealisticGeoHashPrecision.+(1)./(2).toLong)
79 5348 3517 - 3547 Select scala.Long.toDouble GeohashUtils.this.numDistinctGridPoints.toDouble
79 5349 3498 - 3548 Apply org.locationtech.jts.geom.PrecisionModel.<init> new org.locationtech.jts.geom.PrecisionModel(GeohashUtils.this.numDistinctGridPoints.toDouble)
82 5350 3650 - 3671 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.defaultPrecisionModel GeohashUtils.this.defaultPrecisionModel
82 5351 3673 - 3677 Literal <nosymbol> 4326
82 5352 3630 - 3678 Apply org.locationtech.jts.geom.GeometryFactory.<init> new org.locationtech.jts.geom.GeometryFactory(GeohashUtils.this.defaultPrecisionModel, 4326)
102 5353 4719 - 4736 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.getCentroid GeohashUtils.this.getCentroid(geom)
103 5354 4785 - 4809 Apply org.locationtech.jts.geom.Geometry.getEnvelopeInternal geom.getEnvelopeInternal()
103 5355 4751 - 4810 Apply org.locationtech.jts.geom.GeometryFactory.toGeometry GeohashUtils.this.defaultGeometryFactory.toGeometry(geom.getEnvelopeInternal())
106 5356 4930 - 4959 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.minBitsResolution resolutions.minBitsResolution
106 5357 4961 - 4982 TypeApply scala.Option.empty scala.Option.empty[org.locationtech.geomesa.utils.geohash.GeoHash]
106 5358 4929 - 4983 Apply scala.Tuple2.apply scala.Tuple2.apply[Int, Option[org.locationtech.geomesa.utils.geohash.GeoHash]](resolutions.minBitsResolution, scala.Option.empty[org.locationtech.geomesa.utils.geohash.GeoHash])
106 5369 4901 - 5160 Apply scala.collection.IterableLike.foldRight resolutions.range.foldRight[(Int, Option[org.locationtech.geomesa.utils.geohash.GeoHash])](scala.Tuple2.apply[Int, Option[org.locationtech.geomesa.utils.geohash.GeoHash]](resolutions.minBitsResolution, scala.Option.empty[org.locationtech.geomesa.utils.geohash.GeoHash]))(((x0$1: Int, x1$1: (Int, Option[org.locationtech.geomesa.utils.geohash.GeoHash])) => scala.Tuple2.apply[Int, (Int, Option[org.locationtech.geomesa.utils.geohash.GeoHash])](x0$1, x1$1) match { case (_1: Int, _2: (Int, Option[org.locationtech.geomesa.utils.geohash.GeoHash]))(Int, (Int, Option[org.locationtech.geomesa.utils.geohash.GeoHash]))((bits @ _), (orig @ (_1: Int, _2: Option[org.locationtech.geomesa.utils.geohash.GeoHash])(Int, Option[org.locationtech.geomesa.utils.geohash.GeoHash])((res @ _), _))) => { val gh: org.locationtech.geomesa.utils.geohash.GeoHash = GeoHash.apply(centroid.getX(), centroid.getY(), bits); if (geohash.this.GeoHash.toGeometry(gh).contains(env).&&(bits.>=(res))) scala.Tuple2.apply[Int, Some[org.locationtech.geomesa.utils.geohash.GeoHash]](bits, scala.Some.apply[org.locationtech.geomesa.utils.geohash.GeoHash](gh)) else orig } }))
106 5370 4888 - 4898 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.ghOpt ghOpt
107 5368 5019 - 5154 Block <nosymbol> { val gh: org.locationtech.geomesa.utils.geohash.GeoHash = GeoHash.apply(centroid.getX(), centroid.getY(), bits); if (geohash.this.GeoHash.toGeometry(gh).contains(env).&&(bits.>=(res))) scala.Tuple2.apply[Int, Some[org.locationtech.geomesa.utils.geohash.GeoHash]](bits, scala.Some.apply[org.locationtech.geomesa.utils.geohash.GeoHash](gh)) else orig }
108 5359 5047 - 5060 Apply org.locationtech.jts.geom.Point.getX centroid.getX()
108 5360 5062 - 5075 Apply org.locationtech.jts.geom.Point.getY centroid.getY()
108 5361 5039 - 5082 Apply org.locationtech.geomesa.utils.geohash.GeoHash.apply GeoHash.apply(centroid.getX(), centroid.getY(), bits)
109 5362 5115 - 5126 Apply scala.Int.>= bits.>=(res)
109 5363 5095 - 5126 Apply scala.Boolean.&& geohash.this.GeoHash.toGeometry(gh).contains(env).&&(bits.>=(res))
109 5364 5135 - 5143 Apply scala.Some.apply scala.Some.apply[org.locationtech.geomesa.utils.geohash.GeoHash](gh)
109 5365 5128 - 5144 Apply scala.Tuple2.apply scala.Tuple2.apply[Int, Some[org.locationtech.geomesa.utils.geohash.GeoHash]](bits, scala.Some.apply[org.locationtech.geomesa.utils.geohash.GeoHash](gh))
109 5366 5128 - 5144 Block scala.Tuple2.apply scala.Tuple2.apply[Int, Some[org.locationtech.geomesa.utils.geohash.GeoHash]](bits, scala.Some.apply[org.locationtech.geomesa.utils.geohash.GeoHash](gh))
109 5367 5150 - 5154 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.orig orig
113 5371 5246 - 5259 Apply org.locationtech.jts.geom.Point.getX centroid.getX()
113 5372 5261 - 5274 Apply org.locationtech.jts.geom.Point.getY centroid.getY()
113 5373 5276 - 5305 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.minBitsResolution resolutions.minBitsResolution
113 5374 5238 - 5306 Apply org.locationtech.geomesa.utils.geohash.GeoHash.apply GeoHash.apply(centroid.getX(), centroid.getY(), resolutions.minBitsResolution)
113 5375 5222 - 5307 Apply scala.Option.getOrElse ghOpt.getOrElse[org.locationtech.geomesa.utils.geohash.GeoHash](GeoHash.apply(centroid.getX(), centroid.getY(), resolutions.minBitsResolution))
114 5376 5337 - 5357 Select scala.Boolean.unary_! gh.geom.equals(env).unary_!
114 5377 5316 - 5357 Apply scala.Boolean.&& geohash.this.GeoHash.toGeometry(gh).contains(env).unary_!.&&(gh.geom.equals(env).unary_!)
114 5380 5312 - 5312 Literal <nosymbol> ()
114 5381 5312 - 5312 Block <nosymbol> ()
115 5378 5365 - 5517 Throw <nosymbol> throw new scala.`package`.Exception("ERROR: Could not find a suitable ".+(resolutions.minBitsResolution).+("-bit MBR for the target geometry: ").+(geom))
115 5379 5365 - 5517 Block <nosymbol> throw new scala.`package`.Exception("ERROR: Could not find a suitable ".+(resolutions.minBitsResolution).+("-bit MBR for the target geometry: ").+(geom))
129 5382 5783 - 5802 Apply org.locationtech.geomesa.utils.geotools.Conversions.RichGeometry.safeCentroid org.locationtech.geomesa.utils.geotools.Conversions.RichGeometry(geom).safeCentroid()
130 5383 5850 - 5857 Apply org.locationtech.jts.geom.Point.getX pt.getX()
130 5384 5859 - 5866 Apply org.locationtech.jts.geom.Point.getY pt.getY()
130 5385 5835 - 5867 Apply org.locationtech.jts.geom.Coordinate.<init> new org.locationtech.jts.geom.Coordinate(pt.getX(), pt.getY())
130 5386 5807 - 5868 Apply org.locationtech.jts.geom.GeometryFactory.createPoint geom.getFactory().createPoint(new org.locationtech.jts.geom.Coordinate(pt.getX(), pt.getY()))
163 5387 7321 - 7337 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate.areaOutside than.areaOutside
163 5388 7307 - 7337 Apply scala.Double.> DecompositionCandidate.this.areaOutside.>(than.areaOutside)
163 5389 7339 - 7343 Literal <nosymbol> true
163 5390 7339 - 7343 Block <nosymbol> true
165 5391 7384 - 7400 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate.areaOutside than.areaOutside
165 5392 7369 - 7400 Apply scala.Double.== DecompositionCandidate.this.areaOutside.==(than.areaOutside)
165 5393 7402 - 7418 Apply scala.Double.< DecompositionCandidate.this.area.<(than.area)
165 5394 7402 - 7418 Block scala.Double.< DecompositionCandidate.this.area.<(than.area)
165 5397 7365 - 7437 If <nosymbol> if (DecompositionCandidate.this.areaOutside.==(than.areaOutside)) DecompositionCandidate.this.area.<(than.area) else false
166 5395 7432 - 7437 Literal <nosymbol> false
166 5396 7432 - 7437 Block <nosymbol> false
223 5398 9936 - 9945 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate.isLT a.isLT(b)
245 5399 11101 - 11154 Apply scala.Option.getOrElse geomCatcher.opt[Double](targetGeom.getArea()).getOrElse[Double](0.0)
246 5400 11187 - 11242 Apply scala.Option.getOrElse geomCatcher.opt[Double](targetGeom.getLength()).getOrElse[Double](0.0)
253 5401 11469 - 11542 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.PolygonDecompositionCandidate.<init> new GeohashUtils.this.PolygonDecompositionCandidate(gh, multipoly, targetArea, resolutions)
253 5402 11469 - 11542 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.PolygonDecompositionCandidate.<init> new GeohashUtils.this.PolygonDecompositionCandidate(gh, multipoly, targetArea, resolutions)
255 5406 11596 - 11725 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.PolygonDecompositionCandidate.<init> new GeohashUtils.this.PolygonDecompositionCandidate(gh, new org.locationtech.jts.geom.MultiPolygon(scala.Array.apply[org.locationtech.jts.geom.Polygon](polygon)((ClassTag.apply[org.locationtech.jts.geom.Polygon](classOf[org.locationtech.jts.geom.Polygon]): scala.reflect.ClassTag[org.locationtech.jts.geom.Polygon])), polygon.getFactory()), targetArea, resolutions)
255 5407 11596 - 11725 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.PolygonDecompositionCandidate.<init> new GeohashUtils.this.PolygonDecompositionCandidate(gh, new org.locationtech.jts.geom.MultiPolygon(scala.Array.apply[org.locationtech.jts.geom.Polygon](polygon)((ClassTag.apply[org.locationtech.jts.geom.Polygon](classOf[org.locationtech.jts.geom.Polygon]): scala.reflect.ClassTag[org.locationtech.jts.geom.Polygon])), polygon.getFactory()), targetArea, resolutions)
256 5403 11664 - 11678 ApplyToImplicitArgs scala.Array.apply scala.Array.apply[org.locationtech.jts.geom.Polygon](polygon)((ClassTag.apply[org.locationtech.jts.geom.Polygon](classOf[org.locationtech.jts.geom.Polygon]): scala.reflect.ClassTag[org.locationtech.jts.geom.Polygon]))
256 5404 11680 - 11698 Apply org.locationtech.jts.geom.Geometry.getFactory polygon.getFactory()
256 5405 11647 - 11699 Apply org.locationtech.jts.geom.MultiPolygon.<init> new org.locationtech.jts.geom.MultiPolygon(scala.Array.apply[org.locationtech.jts.geom.Polygon](polygon)((ClassTag.apply[org.locationtech.jts.geom.Polygon](classOf[org.locationtech.jts.geom.Polygon]): scala.reflect.ClassTag[org.locationtech.jts.geom.Polygon])), polygon.getFactory())
258 5411 11779 - 11954 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.LineDecompositionCandidate.<init> new GeohashUtils.this.LineDecompositionCandidate(gh, new org.locationtech.jts.geom.MultiLineString(scala.Array.apply[org.locationtech.jts.geom.LineString](line)((ClassTag.apply[org.locationtech.jts.geom.LineString](classOf[org.locationtech.jts.geom.LineString]): scala.reflect.ClassTag[org.locationtech.jts.geom.LineString])), line.getFactory()), targetLength, resolutions)
258 5412 11779 - 11954 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.LineDecompositionCandidate.<init> new GeohashUtils.this.LineDecompositionCandidate(gh, new org.locationtech.jts.geom.MultiLineString(scala.Array.apply[org.locationtech.jts.geom.LineString](line)((ClassTag.apply[org.locationtech.jts.geom.LineString](classOf[org.locationtech.jts.geom.LineString]): scala.reflect.ClassTag[org.locationtech.jts.geom.LineString])), line.getFactory()), targetLength, resolutions)
259 5408 11897 - 11908 ApplyToImplicitArgs scala.Array.apply scala.Array.apply[org.locationtech.jts.geom.LineString](line)((ClassTag.apply[org.locationtech.jts.geom.LineString](classOf[org.locationtech.jts.geom.LineString]): scala.reflect.ClassTag[org.locationtech.jts.geom.LineString]))
259 5409 11910 - 11925 Apply org.locationtech.jts.geom.Geometry.getFactory line.getFactory()
259 5410 11877 - 11926 Apply org.locationtech.jts.geom.MultiLineString.<init> new org.locationtech.jts.geom.MultiLineString(scala.Array.apply[org.locationtech.jts.geom.LineString](line)((ClassTag.apply[org.locationtech.jts.geom.LineString](classOf[org.locationtech.jts.geom.LineString]): scala.reflect.ClassTag[org.locationtech.jts.geom.LineString])), line.getFactory())
261 5413 12008 - 12080 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.LineDecompositionCandidate.<init> new GeohashUtils.this.LineDecompositionCandidate(gh, multiLine, targetLength, resolutions)
261 5414 12008 - 12080 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.LineDecompositionCandidate.<init> new GeohashUtils.this.LineDecompositionCandidate(gh, multiLine, targetLength, resolutions)
263 5415 12134 - 12201 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.PointDecompositionCandidate.<init> new GeohashUtils.this.PointDecompositionCandidate(gh, point, targetArea, resolutions)
263 5416 12134 - 12201 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.PointDecompositionCandidate.<init> new GeohashUtils.this.PointDecompositionCandidate(gh, point, targetArea, resolutions)
265 5417 12296 - 12396 Throw <nosymbol> throw new scala.`package`.Exception(scala.StringContext.apply("Unsupported Geometry type for decomposition: ", "").s(targetGeom.getClass().getName()))
265 5418 12296 - 12396 Block <nosymbol> throw new scala.`package`.Exception(scala.StringContext.apply("Unsupported Geometry type for decomposition: ", "").s(targetGeom.getClass().getName()))
272 5419 12612 - 12637 Apply scala.Int.> candidates.size.>(maxSize)
272 5420 12639 - 12693 Throw <nosymbol> throw new scala.`package`.Exception("Too many candidates upon entry.")
272 5421 12639 - 12693 Block <nosymbol> throw new scala.`package`.Exception("Too many candidates upon entry.")
273 5440 12705 - 13887 Block <nosymbol> { val candidate: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate = candidates.apply(0); val childResolution: Int = candidate.gh.prec.+(resolutions.numBitsIncrement); val candidateBitSet: scala.collection.BitSet = candidate.gh.bitset; val children: List[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate] = resolutions.getNextChildren(candidateBitSet, candidate.gh.prec).map[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate, List[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]](((childBitSet: scala.collection.BitSet) => createDecompositionCandidate(GeoHash.apply(childBitSet, childResolution))))(immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]).filter(((child: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate) => child.intersectsTarget)); val newCandidates: List[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate] = candidates.tail.++[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate, List[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]](children)(immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]).sortWith({ ((a: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate, b: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate) => GeohashUtils.this.decompositionCandidateSorter(a, b)) }); if (newCandidates.size.<=(maxSize).&&(childResolution.<=(resolutions.maxBitsResolution))) decomposeStep(newCandidates) else candidates }
277 5422 13007 - 13020 Apply scala.collection.LinearSeqOptimized.apply candidates.apply(0)
278 5423 13075 - 13103 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.numBitsIncrement resolutions.numBitsIncrement
278 5424 13057 - 13103 Apply scala.Int.+ candidate.gh.prec.+(resolutions.numBitsIncrement)
281 5425 13211 - 13230 Select org.locationtech.geomesa.utils.geohash.GeoHash.bitset candidate.gh.bitset
282 5426 13328 - 13345 Select org.locationtech.geomesa.utils.geohash.GeoHash.prec candidate.gh.prec
282 5429 13350 - 13350 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]
283 5427 13409 - 13446 Apply org.locationtech.geomesa.utils.geohash.GeoHash.apply GeoHash.apply(childBitSet, childResolution)
283 5428 13380 - 13447 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.createDecompositionCandidate createDecompositionCandidate(GeoHash.apply(childBitSet, childResolution))
284 5430 13283 - 13498 Apply scala.collection.TraversableLike.filter resolutions.getNextChildren(candidateBitSet, candidate.gh.prec).map[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate, List[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]](((childBitSet: scala.collection.BitSet) => createDecompositionCandidate(GeoHash.apply(childBitSet, childResolution))))(immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]).filter(((child: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate) => child.intersectsTarget))
287 5431 13626 - 13626 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]
287 5432 13648 - 13676 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.decompositionCandidateSorter GeohashUtils.this.decompositionCandidateSorter(a, b)
287 5433 13609 - 13677 Apply scala.collection.SeqLike.sortWith candidates.tail.++[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate, List[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]](children)(immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate]).sortWith({ ((a: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate, b: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate) => GeohashUtils.this.decompositionCandidateSorter(a, b)) })
290 5434 13781 - 13810 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.maxBitsResolution resolutions.maxBitsResolution
290 5435 13762 - 13810 Apply scala.Int.<= childResolution.<=(resolutions.maxBitsResolution)
290 5436 13726 - 13811 Apply scala.Boolean.&& newCandidates.size.<=(maxSize).&&(childResolution.<=(resolutions.maxBitsResolution))
291 5437 13825 - 13853 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.decomposeStep decomposeStep(newCandidates)
291 5438 13825 - 13853 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.decomposeStep decomposeStep(newCandidates)
292 5439 13869 - 13879 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.candidates candidates
297 5441 13981 - 14031 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.getMinimumBoundingGeohash GeohashUtils.this.getMinimumBoundingGeohash(targetGeom, resolutions)
298 5442 14055 - 14090 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.createDecompositionCandidate createDecompositionCandidate(ghMBR)
301 5443 14198 - 14216 Apply scala.collection.immutable.List.apply scala.collection.immutable.List.apply[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate](candidateMBR)
301 5444 14184 - 14217 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.decomposeStep decomposeStep(scala.collection.immutable.List.apply[org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate](candidateMBR))
304 5445 14308 - 14317 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate.gh keeper.gh
304 5446 14290 - 14290 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeoHash]
304 5447 14254 - 14325 Select scala.collection.immutable.List.toList keepers.withFilter(((check$ifrefutable$1: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate) => (check$ifrefutable$1: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate @unchecked) match { case (keeper @ (_: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate)) => true case _ => false })).map[org.locationtech.geomesa.utils.geohash.GeoHash, List[org.locationtech.geomesa.utils.geohash.GeoHash]](((keeper: org.locationtech.geomesa.utils.geohash.GeohashUtils.DecompositionCandidate) => keeper.gh))(immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeoHash]).toList
308 5448 14478 - 14488 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.targetGeom targetGeom
309 5449 14553 - 14563 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.targetGeom targetGeom
310 5450 14595 - 14624 Apply scala.Int.< targetGeom.getNumPoints().<(100)
310 5451 14628 - 14638 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.targetGeom targetGeom
311 5452 14670 - 14699 Apply scala.Int.< targetGeom.getNumPoints().<(100)
311 5453 14703 - 14713 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.targetGeom targetGeom
312 5454 14778 - 14799 Apply org.locationtech.jts.geom.Geometry.convexHull targetGeom.convexHull()
312 5455 14778 - 14799 Block org.locationtech.jts.geom.Geometry.convexHull targetGeom.convexHull()
327 5456 15617 - 15636 Apply scala.Double./ lon.+(180)./(360.0)
327 5457 15646 - 15650 Literal <nosymbol> -360
327 5458 15615 - 15657 Select scala.Int.toDouble scala.Predef.doubleWrapper(lon.+(180)./(360.0)).floor.*(-360).toInt.toDouble
330 5459 15770 - 15777 Select org.locationtech.jts.geom.Coordinate.x coord.x
330 5460 15748 - 15778 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.degreesLonTranslation degreesLonTranslation(coord.x)
330 5461 15738 - 15778 Apply scala.Double.+ coord.x.+(degreesLonTranslation(coord.x))
330 5462 15780 - 15787 Select org.locationtech.jts.geom.Coordinate.y coord.y
330 5463 15723 - 15788 Apply org.locationtech.jts.geom.Coordinate.<init> new org.locationtech.jts.geom.Coordinate(coord.x.+(degreesLonTranslation(coord.x)), coord.y)
334 5464 15896 - 15919 Apply org.locationtech.jts.geom.Geometry.getCoordinates geometry.getCoordinates()
334 5465 15929 - 15946 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translateCoord translateCoord(c)
334 5466 15923 - 15923 ApplyToImplicitArgs scala.Array.canBuildFrom scala.this.Array.canBuildFrom[org.locationtech.jts.geom.Coordinate]((ClassTag.apply[org.locationtech.jts.geom.Coordinate](classOf[org.locationtech.jts.geom.Coordinate]): scala.reflect.ClassTag[org.locationtech.jts.geom.Coordinate]))
334 5467 15896 - 15947 ApplyToImplicitArgs scala.collection.TraversableLike.map scala.Predef.refArrayOps[org.locationtech.jts.geom.Coordinate](geometry.getCoordinates()).map[org.locationtech.jts.geom.Coordinate, Array[org.locationtech.jts.geom.Coordinate]](((c: org.locationtech.jts.geom.Coordinate) => translateCoord(c)))(scala.this.Array.canBuildFrom[org.locationtech.jts.geom.Coordinate]((ClassTag.apply[org.locationtech.jts.geom.Coordinate](classOf[org.locationtech.jts.geom.Coordinate]): scala.reflect.ClassTag[org.locationtech.jts.geom.Coordinate])))
334 5468 15859 - 15948 Apply org.locationtech.jts.geom.GeometryFactory.createPolygon GeohashUtils.this.defaultGeometryFactory.createPolygon(scala.Predef.refArrayOps[org.locationtech.jts.geom.Coordinate](geometry.getCoordinates()).map[org.locationtech.jts.geom.Coordinate, Array[org.locationtech.jts.geom.Coordinate]](((c: org.locationtech.jts.geom.Coordinate) => translateCoord(c)))(scala.this.Array.canBuildFrom[org.locationtech.jts.geom.Coordinate]((ClassTag.apply[org.locationtech.jts.geom.Coordinate](classOf[org.locationtech.jts.geom.Coordinate]): scala.reflect.ClassTag[org.locationtech.jts.geom.Coordinate]))))
337 5469 16056 - 16079 Apply org.locationtech.jts.geom.Geometry.getCoordinates geometry.getCoordinates()
337 5470 16089 - 16106 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translateCoord translateCoord(c)
337 5471 16083 - 16083 ApplyToImplicitArgs scala.Array.canBuildFrom scala.this.Array.canBuildFrom[org.locationtech.jts.geom.Coordinate]((ClassTag.apply[org.locationtech.jts.geom.Coordinate](classOf[org.locationtech.jts.geom.Coordinate]): scala.reflect.ClassTag[org.locationtech.jts.geom.Coordinate]))
337 5472 16056 - 16107 ApplyToImplicitArgs scala.collection.TraversableLike.map scala.Predef.refArrayOps[org.locationtech.jts.geom.Coordinate](geometry.getCoordinates()).map[org.locationtech.jts.geom.Coordinate, Array[org.locationtech.jts.geom.Coordinate]](((c: org.locationtech.jts.geom.Coordinate) => translateCoord(c)))(scala.this.Array.canBuildFrom[org.locationtech.jts.geom.Coordinate]((ClassTag.apply[org.locationtech.jts.geom.Coordinate](classOf[org.locationtech.jts.geom.Coordinate]): scala.reflect.ClassTag[org.locationtech.jts.geom.Coordinate])))
337 5473 16016 - 16108 Apply org.locationtech.jts.geom.GeometryFactory.createLineString GeohashUtils.this.defaultGeometryFactory.createLineString(scala.Predef.refArrayOps[org.locationtech.jts.geom.Coordinate](geometry.getCoordinates()).map[org.locationtech.jts.geom.Coordinate, Array[org.locationtech.jts.geom.Coordinate]](((c: org.locationtech.jts.geom.Coordinate) => translateCoord(c)))(scala.this.Array.canBuildFrom[org.locationtech.jts.geom.Coordinate]((ClassTag.apply[org.locationtech.jts.geom.Coordinate](classOf[org.locationtech.jts.geom.Coordinate]): scala.reflect.ClassTag[org.locationtech.jts.geom.Coordinate]))))
340 5474 16197 - 16198 Literal <nosymbol> 0
340 5475 16205 - 16230 Apply org.locationtech.jts.geom.Geometry.getNumGeometries geometry.getNumGeometries()
340 5476 16243 - 16267 Apply org.locationtech.jts.geom.Geometry.getGeometryN geometry.getGeometryN(i)
340 5477 16236 - 16236 TypeApply scala.collection.immutable.IndexedSeq.canBuildFrom immutable.this.IndexedSeq.canBuildFrom[org.locationtech.jts.geom.Geometry]
340 5478 16196 - 16269 ApplyToImplicitArgs scala.collection.TraversableLike.map scala.Predef.intWrapper(0).until(geometry.getNumGeometries()).map[org.locationtech.jts.geom.Geometry, scala.collection.immutable.IndexedSeq[org.locationtech.jts.geom.Geometry]](((i: Int) => geometry.getGeometryN(i)))(immutable.this.IndexedSeq.canBuildFrom[org.locationtech.jts.geom.Geometry])
341 5479 16311 - 16358 TypeApply scala.Any.asInstanceOf translateLineString(c).asInstanceOf[org.locationtech.jts.geom.LineString]
341 5480 16304 - 16304 TypeApply scala.collection.immutable.IndexedSeq.canBuildFrom immutable.this.IndexedSeq.canBuildFrom[org.locationtech.jts.geom.LineString]
341 5481 16293 - 16360 ApplyToImplicitArgs scala.collection.TraversableLike.map coords.map[org.locationtech.jts.geom.LineString, scala.collection.immutable.IndexedSeq[org.locationtech.jts.geom.LineString]](((c: org.locationtech.jts.geom.Geometry) => translateLineString(c).asInstanceOf[org.locationtech.jts.geom.LineString]))(immutable.this.IndexedSeq.canBuildFrom[org.locationtech.jts.geom.LineString])
342 5482 16412 - 16430 ApplyToImplicitArgs scala.collection.TraversableOnce.toArray translated.toArray[org.locationtech.jts.geom.LineString]((ClassTag.apply[org.locationtech.jts.geom.LineString](classOf[org.locationtech.jts.geom.LineString]): scala.reflect.ClassTag[org.locationtech.jts.geom.LineString]))
342 5483 16367 - 16431 Apply org.locationtech.jts.geom.GeometryFactory.createMultiLineString GeohashUtils.this.defaultGeometryFactory.createMultiLineString(translated.toArray[org.locationtech.jts.geom.LineString]((ClassTag.apply[org.locationtech.jts.geom.LineString](classOf[org.locationtech.jts.geom.LineString]): scala.reflect.ClassTag[org.locationtech.jts.geom.LineString])))
346 5484 16523 - 16524 Literal <nosymbol> 0
346 5485 16531 - 16556 Apply org.locationtech.jts.geom.Geometry.getNumGeometries geometry.getNumGeometries()
346 5486 16569 - 16593 Apply org.locationtech.jts.geom.Geometry.getGeometryN geometry.getGeometryN(i)
346 5487 16562 - 16562 TypeApply scala.collection.immutable.IndexedSeq.canBuildFrom immutable.this.IndexedSeq.canBuildFrom[org.locationtech.jts.geom.Geometry]
346 5488 16522 - 16595 ApplyToImplicitArgs scala.collection.TraversableLike.map scala.Predef.intWrapper(0).until(geometry.getNumGeometries()).map[org.locationtech.jts.geom.Geometry, scala.collection.immutable.IndexedSeq[org.locationtech.jts.geom.Geometry]](((i: Int) => geometry.getGeometryN(i)))(immutable.this.IndexedSeq.canBuildFrom[org.locationtech.jts.geom.Geometry])
347 5489 16637 - 16678 TypeApply scala.Any.asInstanceOf translatePolygon(c).asInstanceOf[org.locationtech.jts.geom.Polygon]
347 5490 16630 - 16630 TypeApply scala.collection.immutable.IndexedSeq.canBuildFrom immutable.this.IndexedSeq.canBuildFrom[org.locationtech.jts.geom.Polygon]
347 5491 16619 - 16680 ApplyToImplicitArgs scala.collection.TraversableLike.map coords.map[org.locationtech.jts.geom.Polygon, scala.collection.immutable.IndexedSeq[org.locationtech.jts.geom.Polygon]](((c: org.locationtech.jts.geom.Geometry) => translatePolygon(c).asInstanceOf[org.locationtech.jts.geom.Polygon]))(immutable.this.IndexedSeq.canBuildFrom[org.locationtech.jts.geom.Polygon])
348 5492 16729 - 16747 ApplyToImplicitArgs scala.collection.TraversableOnce.toArray translated.toArray[org.locationtech.jts.geom.Polygon]((ClassTag.apply[org.locationtech.jts.geom.Polygon](classOf[org.locationtech.jts.geom.Polygon]): scala.reflect.ClassTag[org.locationtech.jts.geom.Polygon]))
348 5493 16687 - 16748 Apply org.locationtech.jts.geom.GeometryFactory.createMultiPolygon GeohashUtils.this.defaultGeometryFactory.createMultiPolygon(translated.toArray[org.locationtech.jts.geom.Polygon]((ClassTag.apply[org.locationtech.jts.geom.Polygon](classOf[org.locationtech.jts.geom.Polygon]): scala.reflect.ClassTag[org.locationtech.jts.geom.Polygon])))
352 5494 16862 - 16885 Apply org.locationtech.jts.geom.Geometry.getCoordinates geometry.getCoordinates()
352 5495 16895 - 16912 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translateCoord translateCoord(c)
352 5496 16889 - 16889 ApplyToImplicitArgs scala.Array.canBuildFrom scala.this.Array.canBuildFrom[org.locationtech.jts.geom.Coordinate]((ClassTag.apply[org.locationtech.jts.geom.Coordinate](classOf[org.locationtech.jts.geom.Coordinate]): scala.reflect.ClassTag[org.locationtech.jts.geom.Coordinate]))
352 5497 16862 - 16913 ApplyToImplicitArgs scala.collection.TraversableLike.map scala.Predef.refArrayOps[org.locationtech.jts.geom.Coordinate](geometry.getCoordinates()).map[org.locationtech.jts.geom.Coordinate, Array[org.locationtech.jts.geom.Coordinate]](((c: org.locationtech.jts.geom.Coordinate) => translateCoord(c)))(scala.this.Array.canBuildFrom[org.locationtech.jts.geom.Coordinate]((ClassTag.apply[org.locationtech.jts.geom.Coordinate](classOf[org.locationtech.jts.geom.Coordinate]): scala.reflect.ClassTag[org.locationtech.jts.geom.Coordinate])))
352 5498 16822 - 16914 Apply org.locationtech.jts.geom.GeometryFactory.createMultiPoint GeohashUtils.this.defaultGeometryFactory.createMultiPoint(scala.Predef.refArrayOps[org.locationtech.jts.geom.Coordinate](geometry.getCoordinates()).map[org.locationtech.jts.geom.Coordinate, Array[org.locationtech.jts.geom.Coordinate]](((c: org.locationtech.jts.geom.Coordinate) => translateCoord(c)))(scala.this.Array.canBuildFrom[org.locationtech.jts.geom.Coordinate]((ClassTag.apply[org.locationtech.jts.geom.Coordinate](classOf[org.locationtech.jts.geom.Coordinate]): scala.reflect.ClassTag[org.locationtech.jts.geom.Coordinate]))))
355 5499 17029 - 17051 Apply org.locationtech.jts.geom.Geometry.getCoordinate geometry.getCoordinate()
355 5500 17014 - 17052 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translateCoord translateCoord(geometry.getCoordinate())
355 5501 16979 - 17053 Apply org.locationtech.jts.geom.GeometryFactory.createPoint GeohashUtils.this.defaultGeometryFactory.createPoint(translateCoord(geometry.getCoordinate()))
360 5502 17180 - 17206 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translatePolygon translatePolygon(geometry)
360 5503 17180 - 17206 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.translatePolygon translatePolygon(geometry)
361 5504 17243 - 17272 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translateLineString translateLineString(geometry)
361 5505 17243 - 17272 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.translateLineString translateLineString(geometry)
362 5506 17309 - 17343 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translateMultiLineString translateMultiLineString(geometry)
362 5507 17309 - 17343 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.translateMultiLineString translateMultiLineString(geometry)
363 5508 17380 - 17411 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translateMultiPolygon translateMultiPolygon(geometry)
363 5509 17380 - 17411 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.translateMultiPolygon translateMultiPolygon(geometry)
364 5510 17448 - 17477 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translateMultiPoint translateMultiPoint(geometry)
364 5511 17448 - 17477 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.translateMultiPoint translateMultiPoint(geometry)
365 5512 17514 - 17538 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translatePoint translatePoint(geometry)
365 5513 17514 - 17538 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.translatePoint translatePoint(geometry)
369 5522 17558 - 18075 Apply scala.util.Try.apply scala.util.Try.apply[org.locationtech.jts.geom.Geometry]({ val copy: org.locationtech.jts.geom.Geometry = org.locationtech.geomesa.utils.geotools.GeometryUtils.geoFactory.createGeometry(targetGeom); val withinBoundsGeom: org.locationtech.jts.geom.Geometry = if (targetGeom.getEnvelopeInternal().getMinX().<(-180).||(targetGeom.getEnvelopeInternal().getMaxX().>(180))) translateGeometry(copy) else copy; org.locationtech.spatial4j.context.jts.JtsSpatialContext.GEO.makeShape(withinBoundsGeom, true, true).getGeom() })
372 5514 17743 - 17794 Apply org.locationtech.jts.geom.GeometryFactory.createGeometry org.locationtech.geomesa.utils.geotools.GeometryUtils.geoFactory.createGeometry(targetGeom)
374 5515 17877 - 17881 Literal <nosymbol> -180
374 5516 17885 - 17929 Apply scala.Double.> targetGeom.getEnvelopeInternal().getMaxX().>(180)
374 5517 17836 - 17929 Apply scala.Boolean.|| targetGeom.getEnvelopeInternal().getMinX().<(-180).||(targetGeom.getEnvelopeInternal().getMaxX().>(180))
375 5518 17941 - 17964 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.translateGeometry translateGeometry(copy)
375 5519 17941 - 17964 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.translateGeometry translateGeometry(copy)
377 5520 17988 - 17992 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.copy copy
379 5521 18000 - 18069 Apply org.locationtech.spatial4j.shape.jts.JtsGeometry.getGeom org.locationtech.spatial4j.context.jts.JtsSpatialContext.GEO.makeShape(withinBoundsGeom, true, true).getGeom()
393 5523 18549 - 18559 Apply org.locationtech.jts.geom.Point.getX point.getX()
393 5524 18561 - 18571 Apply org.locationtech.jts.geom.Point.getY point.getY()
393 5525 18573 - 18602 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.maxBitsResolution resolutions.maxBitsResolution
393 5526 18541 - 18603 Apply org.locationtech.geomesa.utils.geohash.GeoHash.apply GeoHash.apply(point.getX(), point.getY(), resolutions.maxBitsResolution)
393 5527 18536 - 18604 Apply scala.collection.immutable.List.apply scala.collection.immutable.List.apply[org.locationtech.geomesa.utils.geohash.GeoHash](GeoHash.apply(point.getX(), point.getY(), resolutions.maxBitsResolution))
393 5528 18536 - 18604 Block scala.collection.immutable.List.apply scala.collection.immutable.List.apply[org.locationtech.geomesa.utils.geohash.GeoHash](GeoHash.apply(point.getX(), point.getY(), resolutions.maxBitsResolution))
394 5529 18643 - 18644 Literal <nosymbol> 0
394 5530 18651 - 18670 Apply org.locationtech.jts.geom.GeometryCollection.getNumGeometries gc.getNumGeometries()
394 5533 18687 - 18687 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeoHash]
395 5531 18720 - 18738 Apply org.locationtech.jts.geom.GeometryCollection.getGeometryN gc.getGeometryN(i)
395 5532 18702 - 18771 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.decomposeGeometry GeohashUtils.this.decomposeGeometry(gc.getGeometryN(i), maxSize, resolutions, relaxFit)
396 5534 18642 - 18788 Select scala.collection.SeqLike.distinct scala.Predef.intWrapper(0).until(gc.getNumGeometries()).toList.flatMap[org.locationtech.geomesa.utils.geohash.GeoHash, List[org.locationtech.geomesa.utils.geohash.GeoHash]](((i: Int) => GeohashUtils.this.decomposeGeometry(gc.getGeometryN(i), maxSize, resolutions, relaxFit)))(immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeoHash]).distinct
396 5535 18642 - 18788 Block scala.collection.SeqLike.distinct scala.Predef.intWrapper(0).until(gc.getNumGeometries()).toList.flatMap[org.locationtech.geomesa.utils.geohash.GeoHash, List[org.locationtech.geomesa.utils.geohash.GeoHash]](((i: Int) => GeohashUtils.this.decomposeGeometry(gc.getGeometryN(i), maxSize, resolutions, relaxFit)))(immutable.this.List.canBuildFrom[org.locationtech.geomesa.utils.geohash.GeoHash]).distinct
397 5541 18802 - 19031 Block <nosymbol> { val safeGeom: org.locationtech.jts.geom.Geometry = GeohashUtils.this.getInternationalDateLineSafeGeometry(targetGeom).getOrElse[org.locationtech.jts.geom.Geometry](targetGeom); GeohashUtils.this.decomposeGeometry_(if (relaxFit) GeohashUtils.this.getDecomposableGeometry(safeGeom) else safeGeom, maxSize, resolutions) }
398 5536 18828 - 18898 Apply scala.util.Try.getOrElse GeohashUtils.this.getInternationalDateLineSafeGeometry(targetGeom).getOrElse[org.locationtech.jts.geom.Geometry](targetGeom)
399 5540 18907 - 19031 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.decomposeGeometry_ GeohashUtils.this.decomposeGeometry_(if (relaxFit) GeohashUtils.this.getDecomposableGeometry(safeGeom) else safeGeom, maxSize, resolutions)
400 5537 18951 - 18984 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.getDecomposableGeometry GeohashUtils.this.getDecomposableGeometry(safeGeom)
400 5538 18951 - 18984 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.getDecomposableGeometry GeohashUtils.this.getDecomposableGeometry(safeGeom)
401 5539 19000 - 19008 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.safeGeom safeGeom
427 5542 19994 - 20035 Apply scala.Option.getOrElse set.headOption.map[Int](((x$1: String) => x$1.length())).getOrElse[Int](0)
429 5543 20059 - 20060 Literal <nosymbol> 0
430 5544 20100 - 20109 Apply scala.collection.IndexedSeqOptimized.take scala.Predef.augmentString(x$2).take(i)
430 5545 20099 - 20099 TypeApply scala.collection.Seq.canBuildFrom collection.this.Seq.canBuildFrom[String]
430 5552 20084 - 20084 Apply scala.Tuple2.apply scala.Tuple2.apply[String, String](hash, newStr)
430 5553 20089 - 20089 TypeApply scala.collection.Seq.canBuildFrom collection.this.Seq.canBuildFrom[(String, String)]
430 5555 20089 - 20089 TypeApply scala.collection.Seq.canBuildFrom collection.this.Seq.canBuildFrom[String]
430 5556 20084 - 20200 ApplyToImplicitArgs scala.collection.TraversableLike.map set.map[String, Seq[String]](((x$2: String) => scala.Predef.augmentString(x$2).take(i)))(collection.this.Seq.canBuildFrom[String]).distinct.map[(String, String), Seq[(String, String)]](((hash: String) => { val newStr: String = scala.Predef.augmentString(hash).take(i).+(scala.Predef.augmentString("").padTo[Any, scala.collection.immutable.IndexedSeq[Any]](len.-(i), ".")(scala.Predef.fallbackStringCanBuildFrom[Any]).mkString); scala.Tuple2.apply[String, String](hash, newStr) }))(collection.this.Seq.canBuildFrom[(String, String)]).map[String, Seq[String]](((x$3: (String, String)) => (x$3: (String, String) @unchecked) match { case (_1: String, _2: String)(String, String)((hash @ _), (newStr @ _)) => newStr }))(collection.this.Seq.canBuildFrom[String])
431 5546 20150 - 20152 Literal <nosymbol> ""
431 5547 20159 - 20166 Apply scala.Int.- len.-(i)
431 5548 20168 - 20171 Literal <nosymbol> "."
431 5549 20158 - 20158 TypeApply scala.LowPriorityImplicits.fallbackStringCanBuildFrom scala.Predef.fallbackStringCanBuildFrom[Any]
431 5550 20150 - 20181 Select scala.collection.TraversableOnce.mkString scala.Predef.augmentString("").padTo[Any, scala.collection.immutable.IndexedSeq[Any]](len.-(i), ".")(scala.Predef.fallbackStringCanBuildFrom[Any]).mkString
431 5551 20135 - 20181 Apply java.lang.String.+ scala.Predef.augmentString(hash).take(i).+(scala.Predef.augmentString("").padTo[Any, scala.collection.immutable.IndexedSeq[Any]](len.-(i), ".")(scala.Predef.fallbackStringCanBuildFrom[Any]).mkString)
432 5554 20194 - 20200 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.newStr newStr
432 5557 20207 - 20218 Apply scala.Int.+ maxSize.+(1)
432 5558 20040 - 20219 Apply scala.collection.Iterator.take scala.Predef.intWrapper(0).to(len).iterator.flatMap[String](((i: Int) => set.map[String, Seq[String]](((x$2: String) => scala.Predef.augmentString(x$2).take(i)))(collection.this.Seq.canBuildFrom[String]).distinct.map[(String, String), Seq[(String, String)]](((hash: String) => { val newStr: String = scala.Predef.augmentString(hash).take(i).+(scala.Predef.augmentString("").padTo[Any, scala.collection.immutable.IndexedSeq[Any]](len.-(i), ".")(scala.Predef.fallbackStringCanBuildFrom[Any]).mkString); scala.Tuple2.apply[String, String](hash, newStr) }))(collection.this.Seq.canBuildFrom[(String, String)]).map[String, Seq[String]](((x$3: (String, String)) => (x$3: (String, String) @unchecked) match { case (_1: String, _2: String)(String, String)((hash @ _), (newStr @ _)) => newStr }))(collection.this.Seq.canBuildFrom[String]))).take(maxSize.+(1))
437 5559 20317 - 20331 Apply org.locationtech.jts.geom.Geometry.buffer g.buffer(1.0E-6)
437 5560 20317 - 20331 Block org.locationtech.jts.geom.Geometry.buffer g.buffer(1.0E-6)
439 5561 20365 - 20380 Apply scala.Double.> g.getArea().>(0.0)
439 5562 20382 - 20383 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.g g
439 5565 20361 - 20424 If <nosymbol> if (g.getArea().>(0.0)) g else org.locationtech.geomesa.utils.geotools.Conversions.RichGeometry(g).safeCentroid().buffer(1.0E-6)
440 5563 20395 - 20424 Apply org.locationtech.jts.geom.Geometry.buffer org.locationtech.geomesa.utils.geotools.Conversions.RichGeometry(g).safeCentroid().buffer(1.0E-6)
440 5564 20395 - 20424 Block org.locationtech.jts.geom.Geometry.buffer org.locationtech.geomesa.utils.geotools.Conversions.RichGeometry(g).safeCentroid().buffer(1.0E-6)
441 5571 20445 - 20550 Block <nosymbol> { val env: org.locationtech.jts.geom.Geometry = g.getEnvelope(); if (env.getArea().>(0.0)) env else env.getCentroid().buffer(1.0E-6) }
442 5566 20464 - 20477 Apply org.locationtech.jts.geom.Geometry.getEnvelope g.getEnvelope()
443 5567 20488 - 20505 Apply scala.Double.> env.getArea().>(0.0)
443 5568 20507 - 20510 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.env env
444 5569 20522 - 20550 Apply org.locationtech.jts.geom.Geometry.buffer env.getCentroid().buffer(1.0E-6)
444 5570 20522 - 20550 Block org.locationtech.jts.geom.Geometry.buffer env.getCentroid().buffer(1.0E-6)
498 5710 23500 - 29720 Apply scala.util.Try.apply scala.util.Try.apply[Seq[String]]({ val cover: org.locationtech.jts.geom.Geometry = GeohashUtils.this.promoteToRegion(geom); val maxBits: Int = offset.+(length).*(5); val minBits: Int = offset.*(5); val usedBits: Int = length.*(5); val allResolutions: org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange = GeohashUtils.this.ResolutionRange.apply(0, java.lang.Math.min(35, maxBits), 1); val maxKeys: Int = java.lang.Math.min(2.<<(java.lang.Math.min(usedBits, 29)), MAX_KEYS_IN_LIST); val polyCentroid: org.locationtech.jts.geom.Point = org.locationtech.geomesa.utils.geotools.Conversions.RichGeometry(cover).safeCentroid(); val ghMBR: org.locationtech.geomesa.utils.geohash.GeoHash = GeohashUtils.this.getMinimumBoundingGeohash(geom, allResolutions); case class BitPrefixes extends AnyRef with Product with Serializable { <caseaccessor> <paramaccessor> private[this] val prefixes: Seq[String] = _; <stable> <caseaccessor> <accessor> <paramaccessor> def prefixes: Seq[String] = BitPrefixes.this.prefixes; def <init>(prefixes: Seq[String]): BitPrefixes = { BitPrefixes.super.<init>(); () }; private[this] val hasEverythingPrefix: Boolean = BitPrefixes.this.prefixes.exists(((prefix: String) => prefix.length().<=(minBits))); <stable> <accessor> def hasEverythingPrefix: Boolean = BitPrefixes.this.hasEverythingPrefix; private[this] val entailedSize: Int = if (BitPrefixes.this.hasEverythingPrefix) maxKeys else java.lang.Math.min(1.<<(usedBits), BitPrefixes.this.prefixes.foldLeft[Int](0)(((sumSoFar: Int, prefix: String) => sumSoFar.+(1.<<(java.lang.Math.min(usedBits, maxBits.-(prefix.length()))))))); <stable> <accessor> def entailedSize: Int = BitPrefixes.this.entailedSize; private[this] val usesAll: Boolean = BitPrefixes.this.prefixes.exists(((prefix: String) => prefix.length().<=(minBits))).||(BitPrefixes.this.entailedSize.==(maxKeys)); <stable> <accessor> def usesAll: Boolean = BitPrefixes.this.usesAll; def hasRoom: Boolean = BitPrefixes.this.entailedSize.<=(maxKeys); def notDone: Boolean = BitPrefixes.this.usesAll.unary_!.&&(BitPrefixes.this.hasRoom); def overflowed: Boolean = if (BitPrefixes.this.usesAll) 1.<<(usedBits).>(maxKeys) else BitPrefixes.this.entailedSize.>(maxKeys); def generateAll(prefix: String): Seq[String] = { val prefixHash: String = GeoHash.fromBinaryString(prefix).hash; if (prefixHash.length().<(length)) { val charSeqs: List[Seq[Char]] = GeohashUtils.this.Base32Padding.apply(length.-(prefixHash.length())); org.locationtech.geomesa.utils.iterators.CartesianProductIterable.apply(charSeqs).toList.map[String, Seq[String]](((x$4: Seq[_]) => prefixHash.+(x$4.mkString)))(immutable.this.List.canBuildFrom[String]) } else scala.collection.Seq.apply[String](prefixHash) }; def generateSome: Seq[String] = BitPrefixes.this.prefixes.foldLeft[scala.collection.immutable.HashSet[String]](scala.collection.immutable.HashSet.apply[String]())(((ghsSoFar: scala.collection.immutable.HashSet[String], prefix: String) => { val bitsToBoundary: Int = 65.-(prefix.length()).%(5); val bases: Seq[String] = if (bitsToBoundary.==(0)) scala.collection.Seq.apply[String](prefix) else { val fillers: List[Seq[Char]] = GeohashUtils.this.BinaryPadding.apply(bitsToBoundary); val result: List[String] = org.locationtech.geomesa.utils.iterators.CartesianProductIterable.apply(fillers).toList.map[String, List[String]](((x$5: Seq[_]) => prefix.+(x$5.mkString)))(immutable.this.List.canBuildFrom[String]); result }; bases.foldLeft[scala.collection.immutable.HashSet[String]](ghsSoFar)(((ghs: scala.collection.immutable.HashSet[String], base: String) => { val baseTrimmed: String = scala.Predef.augmentString(base).drop(minBits); val newSubs: Seq[String] = BitPrefixes.this.generateAll(baseTrimmed); ghs.++(newSubs) })) })).toSeq; def toSeq: Seq[String] = if (BitPrefixes.this.usesAll) BitPrefixes.this.generateAll("") else BitPrefixes.this.generateSome; <synthetic> def copy(prefixes: Seq[String] = prefixes): BitPrefixes = new BitPrefixes(prefixes); <synthetic> def copy$default$1: Seq[String] = BitPrefixes.this.prefixes; override <synthetic> def productPrefix: String = "BitPrefixes"; <synthetic> def productArity: Int = 1; <synthetic> def productElement(x$1: Int): Any = x$1 match { case 0 => BitPrefixes.this.prefixes case _ => throw new IndexOutOfBoundsException(x$1.toString()) }; override <synthetic> def productIterator: Iterator[Any] = scala.runtime.ScalaRunTime.typedProductIterator[Any](BitPrefixes.this); <synthetic> def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[BitPrefixes](); override <synthetic> def hashCode(): Int = scala.runtime.ScalaRunTime._hashCode(BitPrefixes.this); override <synthetic> def toString(): String = scala.runtime.ScalaRunTime._toString(BitPrefixes.this); override <synthetic> def equals(x$1: Any): Boolean = BitPrefixes.this.eq(x$1.asInstanceOf[Object]).||(x$1 match { case (_: BitPrefixes) => true case _ => false }.&&({ <synthetic> val BitPrefixes$1: BitPrefixes = x$1.asInstanceOf[BitPrefixes]; BitPrefixes.this.prefixes.==(BitPrefixes$1.prefixes).&&(BitPrefixes$1.canEqual(BitPrefixes.this)) })) }; <synthetic> object BitPrefixes extends scala.runtime.AbstractFunction1[Seq[String],BitPrefixes] with Serializable { def <init>(): BitPrefixes.type = { BitPrefixes.super.<init>(); () }; final override <synthetic> def toString(): String = "BitPrefixes"; case <synthetic> def apply(prefixes: Seq[String]): BitPrefixes = new BitPrefixes(prefixes); case <synthetic> def unapply(x$0: BitPrefixes): Option[Seq[String]] = if (x$0.==(null)) scala.None else Some.apply[Seq[String]](x$0.prefixes) }; def considerCandidate(candidate: org.locationtech.geomesa.utils.geohash.GeoHash): Seq[String] = { val bitString: String = candidate.toBinaryString; if (geom.intersects(candidate.geom).unary_!) return scala.collection.immutable.Nil else (); if (cover.covers(candidate.geom).||(scala.Predef.augmentString(bitString).size.==(maxBits))) scala.collection.Seq.apply[String](bitString) else if (scala.Predef.augmentString(bitString).size.<(maxBits)) { val gh0: org.locationtech.geomesa.utils.geohash.GeoHash = GeoHash.fromBinaryString(bitString.+("0")); val gh1: org.locationtech.geomesa.utils.geohash.GeoHash = GeoHash.fromBinaryString(bitString.+("1")); val d0: Double = java.lang.Math.hypot(gh0.getPoint.getX().-(polyCentroid.getX()), gh0.getPoint.getY().-(polyCentroid.getY())); val d1: Double = java.lang.Math.hypot(gh1.getPoint.getX().-(polyCentroid.getX()), gh1.getPoint.getY().-(polyCentroid.getY())); <synthetic> <artifact> private[this] val x$6: (org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash) = (if (d0.<=(d1)) scala.Tuple2.apply[org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash](gh0, gh1) else scala.Tuple2.apply[org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash](gh1, gh0): (org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash) @unchecked) match { case (_1: org.locationtech.geomesa.utils.geohash.GeoHash, _2: org.locationtech.geomesa.utils.geohash.GeoHash)(org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash)((firstChild @ _), (secondChild @ _)) => scala.Tuple2.apply[org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash](firstChild, secondChild) }; val firstChild: org.locationtech.geomesa.utils.geohash.GeoHash = x$6._1; val secondChild: org.locationtech.geomesa.utils.geohash.GeoHash = x$6._2; val firstChildList: Seq[String] = considerCandidate(firstChild); firstChildList.++[String, Seq[String]](firstChildList.headOption match { case (value: String)Some[String]((bitStr @ _)) if bitStr.length().<=(minBits) => scala.collection.immutable.Nil case _ => considerCandidate(secondChild) })(collection.this.Seq.canBuildFrom[String]) } else scala.collection.immutable.Nil }; val bitPrefixes: BitPrefixes = BitPrefixes.apply(if (ghMBR.prec.<=(maxBits)) considerCandidate(ghMBR) else scala.collection.Seq.apply[String](scala.Predef.augmentString(scala.Predef.augmentString(ghMBR.toBinaryString).drop(minBits)).take(usedBits))); if (bitPrefixes.overflowed) throw new java.lang.IllegalStateException("Bit prefixes overflowed while calculating unique Geohash substrings in polygon using the following parameters: ".+(scala.StringContext.apply("\\nGeometry: ", " \\nOffset: ", " \\nLength: ", " \\nMax Keys in List: ", "").s(geom, offset, length, MAX_KEYS_IN_LIST))) else (); val unDotted: Seq[String] = bitPrefixes.toSeq; if (includeDots) if (unDotted.size.<(maxKeys)) { val keepers: List[String] = GeohashUtils.this.getGeohashStringDottingIterator(unDotted, MAX_KEYS_IN_LIST).take(MAX_KEYS_IN_LIST.+(1)).toList; if (keepers.size.<=(MAX_KEYS_IN_LIST)) keepers.toSeq else scala.collection.Seq.apply[Nothing]() } else scala.collection.Seq.apply[Nothing]() else unDotted })
500 5572 23523 - 23544 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.promoteToRegion GeohashUtils.this.promoteToRegion(geom)
503 5573 23607 - 23628 Apply scala.Int.* offset.+(length).*(5)
504 5574 23647 - 23657 Apply scala.Int.* offset.*(5)
505 5575 23677 - 23687 Apply scala.Int.* length.*(5)
506 5576 23729 - 23730 Literal <nosymbol> 0
506 5577 23732 - 23753 Apply java.lang.Math.min java.lang.Math.min(35, maxBits)
506 5578 23755 - 23756 Literal <nosymbol> 1
506 5579 23713 - 23757 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.ResolutionRange.apply GeohashUtils.this.ResolutionRange.apply(0, java.lang.Math.min(35, maxBits), 1)
507 5580 23785 - 23786 Literal <nosymbol> 2
507 5581 23790 - 23812 Apply java.lang.Math.min java.lang.Math.min(usedBits, 29)
507 5582 23785 - 23812 Apply scala.Int.<< 2.<<(java.lang.Math.min(usedBits, 29))
507 5583 23776 - 23831 Apply java.lang.Math.min java.lang.Math.min(2.<<(java.lang.Math.min(usedBits, 29)), MAX_KEYS_IN_LIST)
508 5584 23855 - 23875 Apply org.locationtech.geomesa.utils.geotools.Conversions.RichGeometry.safeCentroid org.locationtech.geomesa.utils.geotools.Conversions.RichGeometry(cover).safeCentroid()
511 5585 23966 - 24013 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.getMinimumBoundingGeohash GeohashUtils.this.getMinimumBoundingGeohash(geom, allResolutions)
516 5586 24194 - 24218 Apply scala.Int.<= prefix.length().<=(minBits)
516 5587 24168 - 24219 Apply scala.collection.IterableLike.exists BitPrefixes.this.prefixes.exists(((prefix: String) => prefix.length().<=(minBits)))
520 5588 24323 - 24342 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.hasEverythingPrefix BitPrefixes.this.hasEverythingPrefix
520 5589 24344 - 24351 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.maxKeys maxKeys
521 5599 24365 - 24542 Apply java.lang.Math.min java.lang.Math.min(1.<<(usedBits), BitPrefixes.this.prefixes.foldLeft[Int](0)(((sumSoFar: Int, prefix: String) => sumSoFar.+(1.<<(java.lang.Math.min(usedBits, maxBits.-(prefix.length())))))))
521 5600 24365 - 24542 Block java.lang.Math.min java.lang.Math.min(1.<<(usedBits), BitPrefixes.this.prefixes.foldLeft[Int](0)(((sumSoFar: Int, prefix: String) => sumSoFar.+(1.<<(java.lang.Math.min(usedBits, maxBits.-(prefix.length())))))))
522 5590 24385 - 24398 Apply scala.Int.<< 1.<<(usedBits)
523 5591 24428 - 24429 Literal <nosymbol> 0
523 5598 24410 - 24541 Apply scala.collection.TraversableOnce.foldLeft BitPrefixes.this.prefixes.foldLeft[Int](0)(((sumSoFar: Int, prefix: String) => sumSoFar.+(1.<<(java.lang.Math.min(usedBits, maxBits.-(prefix.length()))))))
524 5592 24479 - 24480 Literal <nosymbol> 1
524 5593 24513 - 24526 Apply java.lang.String.length prefix.length()
524 5594 24503 - 24526 Apply scala.Int.- maxBits.-(prefix.length())
524 5595 24484 - 24527 Apply java.lang.Math.min java.lang.Math.min(usedBits, maxBits.-(prefix.length()))
524 5596 24479 - 24527 Apply scala.Int.<< 1.<<(java.lang.Math.min(usedBits, maxBits.-(prefix.length())))
524 5597 24467 - 24528 Apply scala.Int.+ sumSoFar.+(1.<<(java.lang.Math.min(usedBits, maxBits.-(prefix.length()))))
530 5601 24768 - 24792 Apply scala.Int.<= prefix.length().<=(minBits)
530 5603 24742 - 24828 Apply scala.Boolean.|| BitPrefixes.this.prefixes.exists(((prefix: String) => prefix.length().<=(minBits))).||(BitPrefixes.this.entailedSize.==(maxKeys))
531 5602 24805 - 24828 Apply scala.Int.== BitPrefixes.this.entailedSize.==(maxKeys)
534 5604 24914 - 24937 Apply scala.Int.<= BitPrefixes.this.entailedSize.<=(maxKeys)
536 5605 24971 - 24978 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.hasRoom BitPrefixes.this.hasRoom
536 5606 24959 - 24978 Apply scala.Boolean.&& BitPrefixes.this.usesAll.unary_!.&&(BitPrefixes.this.hasRoom)
539 5607 25015 - 25022 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.usesAll BitPrefixes.this.usesAll
540 5608 25036 - 25061 Apply scala.Int.> 1.<<(usedBits).>(maxKeys)
540 5609 25036 - 25061 Block scala.Int.> 1.<<(usedBits).>(maxKeys)
542 5610 25089 - 25111 Apply scala.Int.> BitPrefixes.this.entailedSize.>(maxKeys)
542 5611 25089 - 25111 Block scala.Int.> BitPrefixes.this.entailedSize.>(maxKeys)
549 5612 25338 - 25364 Apply scala.Int.< prefixHash.length().<(length)
549 5620 25366 - 25525 Block <nosymbol> { val charSeqs: List[Seq[Char]] = GeohashUtils.this.Base32Padding.apply(length.-(prefixHash.length())); org.locationtech.geomesa.utils.iterators.CartesianProductIterable.apply(charSeqs).toList.map[String, Seq[String]](((x$4: Seq[_]) => prefixHash.+(x$4.mkString)))(immutable.this.List.canBuildFrom[String]) }
550 5613 25416 - 25433 Apply java.lang.String.length prefixHash.length()
550 5614 25407 - 25433 Apply scala.Int.- length.-(prefixHash.length())
550 5615 25393 - 25434 Apply scala.collection.SeqLike.apply GeohashUtils.this.Base32Padding.apply(length.-(prefixHash.length()))
551 5616 25504 - 25514 Select scala.collection.TraversableOnce.mkString x$4.mkString
551 5617 25491 - 25514 Apply java.lang.String.+ prefixHash.+(x$4.mkString)
551 5618 25490 - 25490 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[String]
551 5619 25445 - 25515 ApplyToImplicitArgs scala.collection.immutable.List.map org.locationtech.geomesa.utils.iterators.CartesianProductIterable.apply(charSeqs).toList.map[String, Seq[String]](((x$4: Seq[_]) => prefixHash.+(x$4.mkString)))(immutable.this.List.canBuildFrom[String])
552 5621 25531 - 25546 Apply scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[String](prefixHash)
552 5622 25531 - 25546 Block scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[String](prefixHash)
565 5623 26205 - 26222 Apply scala.collection.generic.GenericCompanion.apply scala.collection.immutable.HashSet.apply[String]()
567 5624 26340 - 26364 Apply scala.Int.% 65.-(prefix.length()).%(5)
569 5625 26403 - 26422 Apply scala.Int.== bitsToBoundary.==(0)
569 5626 26424 - 26435 Apply scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[String](prefix)
569 5627 26424 - 26435 Block scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[String](prefix)
570 5633 26453 - 26640 Block <nosymbol> { val fillers: List[Seq[Char]] = GeohashUtils.this.BinaryPadding.apply(bitsToBoundary); val result: List[String] = org.locationtech.geomesa.utils.iterators.CartesianProductIterable.apply(fillers).toList.map[String, List[String]](((x$5: Seq[_]) => prefix.+(x$5.mkString)))(immutable.this.List.canBuildFrom[String]); result }
571 5628 26483 - 26512 Apply scala.collection.SeqLike.apply GeohashUtils.this.BinaryPadding.apply(bitsToBoundary)
572 5629 26594 - 26604 Select scala.collection.TraversableOnce.mkString x$5.mkString
572 5630 26585 - 26604 Apply java.lang.String.+ prefix.+(x$5.mkString)
572 5631 26584 - 26584 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[String]
572 5632 26540 - 26605 ApplyToImplicitArgs scala.collection.immutable.List.map org.locationtech.geomesa.utils.iterators.CartesianProductIterable.apply(fillers).toList.map[String, List[String]](((x$5: Seq[_]) => prefix.+(x$5.mkString)))(immutable.this.List.canBuildFrom[String])
575 5637 26651 - 26832 Apply scala.collection.TraversableOnce.foldLeft bases.foldLeft[scala.collection.immutable.HashSet[String]](ghsSoFar)(((ghs: scala.collection.immutable.HashSet[String], base: String) => { val baseTrimmed: String = scala.Predef.augmentString(base).drop(minBits); val newSubs: Seq[String] = BitPrefixes.this.generateAll(baseTrimmed); ghs.++(newSubs) }))
576 5634 26723 - 26741 Apply scala.collection.IndexedSeqOptimized.drop scala.Predef.augmentString(base).drop(minBits)
577 5635 26768 - 26792 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.generateAll BitPrefixes.this.generateAll(baseTrimmed)
578 5636 26805 - 26819 Apply scala.collection.SetLike.++ ghs.++(newSubs)
580 5638 26187 - 26849 Select scala.collection.SetLike.toSeq BitPrefixes.this.prefixes.foldLeft[scala.collection.immutable.HashSet[String]](scala.collection.immutable.HashSet.apply[String]())(((ghsSoFar: scala.collection.immutable.HashSet[String], prefix: String) => { val bitsToBoundary: Int = 65.-(prefix.length()).%(5); val bases: Seq[String] = if (bitsToBoundary.==(0)) scala.collection.Seq.apply[String](prefix) else { val fillers: List[Seq[Char]] = GeohashUtils.this.BinaryPadding.apply(bitsToBoundary); val result: List[String] = org.locationtech.geomesa.utils.iterators.CartesianProductIterable.apply(fillers).toList.map[String, List[String]](((x$5: Seq[_]) => prefix.+(x$5.mkString)))(immutable.this.List.canBuildFrom[String]); result }; bases.foldLeft[scala.collection.immutable.HashSet[String]](ghsSoFar)(((ghs: scala.collection.immutable.HashSet[String], base: String) => { val baseTrimmed: String = scala.Predef.augmentString(base).drop(minBits); val newSubs: Seq[String] = BitPrefixes.this.generateAll(baseTrimmed); ghs.++(newSubs) })) })).toSeq
584 5639 26902 - 26909 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.usesAll BitPrefixes.this.usesAll
584 5640 26911 - 26926 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.generateAll BitPrefixes.this.generateAll("")
584 5641 26911 - 26926 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.generateAll BitPrefixes.this.generateAll("")
585 5642 26940 - 26952 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.generateSome BitPrefixes.this.generateSome
585 5643 26940 - 26952 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.generateSome BitPrefixes.this.generateSome
591 5644 27153 - 27177 Select org.locationtech.geomesa.utils.geohash.GeoHash.toBinaryString candidate.toBinaryString
593 5645 27189 - 27221 Select scala.Boolean.unary_! geom.intersects(candidate.geom).unary_!
593 5646 27230 - 27233 Select scala.collection.immutable.Nil scala.collection.immutable.Nil
593 5647 27223 - 27233 Return org.locationtech.geomesa.utils.geohash.GeohashUtils.considerCandidate return scala.collection.immutable.Nil
593 5648 27185 - 27185 Literal <nosymbol> ()
593 5649 27185 - 27185 Block <nosymbol> ()
595 5650 27278 - 27303 Apply scala.Int.== scala.Predef.augmentString(bitString).size.==(maxBits)
595 5651 27245 - 27304 Apply scala.Boolean.|| cover.covers(candidate.geom).||(scala.Predef.augmentString(bitString).size.==(maxBits))
596 5652 27316 - 27330 Apply scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[String](bitString)
596 5653 27316 - 27330 Block scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[String](bitString)
598 5654 27358 - 27382 Apply scala.Int.< scala.Predef.augmentString(bitString).size.<(maxBits)
598 5680 27384 - 28513 Block <nosymbol> { val gh0: org.locationtech.geomesa.utils.geohash.GeoHash = GeoHash.fromBinaryString(bitString.+("0")); val gh1: org.locationtech.geomesa.utils.geohash.GeoHash = GeoHash.fromBinaryString(bitString.+("1")); val d0: Double = java.lang.Math.hypot(gh0.getPoint.getX().-(polyCentroid.getX()), gh0.getPoint.getY().-(polyCentroid.getY())); val d1: Double = java.lang.Math.hypot(gh1.getPoint.getX().-(polyCentroid.getX()), gh1.getPoint.getY().-(polyCentroid.getY())); <synthetic> <artifact> private[this] val x$6: (org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash) = (if (d0.<=(d1)) scala.Tuple2.apply[org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash](gh0, gh1) else scala.Tuple2.apply[org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash](gh1, gh0): (org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash) @unchecked) match { case (_1: org.locationtech.geomesa.utils.geohash.GeoHash, _2: org.locationtech.geomesa.utils.geohash.GeoHash)(org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash)((firstChild @ _), (secondChild @ _)) => scala.Tuple2.apply[org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash](firstChild, secondChild) }; val firstChild: org.locationtech.geomesa.utils.geohash.GeoHash = x$6._1; val secondChild: org.locationtech.geomesa.utils.geohash.GeoHash = x$6._2; val firstChildList: Seq[String] = considerCandidate(firstChild); firstChildList.++[String, Seq[String]](firstChildList.headOption match { case (value: String)Some[String]((bitStr @ _)) if bitStr.length().<=(minBits) => scala.collection.immutable.Nil case _ => considerCandidate(secondChild) })(collection.this.Seq.canBuildFrom[String]) }
598 5683 27354 - 28522 If <nosymbol> if (scala.Predef.augmentString(bitString).size.<(maxBits)) { val gh0: org.locationtech.geomesa.utils.geohash.GeoHash = GeoHash.fromBinaryString(bitString.+("0")); val gh1: org.locationtech.geomesa.utils.geohash.GeoHash = GeoHash.fromBinaryString(bitString.+("1")); val d0: Double = java.lang.Math.hypot(gh0.getPoint.getX().-(polyCentroid.getX()), gh0.getPoint.getY().-(polyCentroid.getY())); val d1: Double = java.lang.Math.hypot(gh1.getPoint.getX().-(polyCentroid.getX()), gh1.getPoint.getY().-(polyCentroid.getY())); <synthetic> <artifact> private[this] val x$6: (org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash) = (if (d0.<=(d1)) scala.Tuple2.apply[org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash](gh0, gh1) else scala.Tuple2.apply[org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash](gh1, gh0): (org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash) @unchecked) match { case (_1: org.locationtech.geomesa.utils.geohash.GeoHash, _2: org.locationtech.geomesa.utils.geohash.GeoHash)(org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash)((firstChild @ _), (secondChild @ _)) => scala.Tuple2.apply[org.locationtech.geomesa.utils.geohash.GeoHash, org.locationtech.geomesa.utils.geohash.GeoHash](firstChild, secondChild) }; val firstChild: org.locationtech.geomesa.utils.geohash.GeoHash = x$6._1; val secondChild: org.locationtech.geomesa.utils.geohash.GeoHash = x$6._2; val firstChildList: Seq[String] = considerCandidate(firstChild); firstChildList.++[String, Seq[String]](firstChildList.headOption match { case (value: String)Some[String]((bitStr @ _)) if bitStr.length().<=(minBits) => scala.collection.immutable.Nil case _ => considerCandidate(secondChild) })(collection.this.Seq.canBuildFrom[String]) } else scala.collection.immutable.Nil
603 5655 27709 - 27724 Apply java.lang.String.+ bitString.+("0")
603 5656 27684 - 27725 Apply org.locationtech.geomesa.utils.geohash.GeoHash.fromBinaryString GeoHash.fromBinaryString(bitString.+("0"))
604 5657 27771 - 27786 Apply java.lang.String.+ bitString.+("1")
604 5658 27746 - 27787 Apply org.locationtech.geomesa.utils.geohash.GeoHash.fromBinaryString GeoHash.fromBinaryString(bitString.+("1"))
605 5659 27838 - 27855 Apply org.locationtech.jts.geom.Point.getX polyCentroid.getX()
605 5660 27818 - 27855 Apply scala.Double.- gh0.getPoint.getX().-(polyCentroid.getX())
605 5661 27877 - 27894 Apply org.locationtech.jts.geom.Point.getY polyCentroid.getY()
605 5662 27857 - 27894 Apply scala.Double.- gh0.getPoint.getY().-(polyCentroid.getY())
605 5663 27807 - 27895 Apply java.lang.Math.hypot java.lang.Math.hypot(gh0.getPoint.getX().-(polyCentroid.getX()), gh0.getPoint.getY().-(polyCentroid.getY()))
606 5664 27946 - 27963 Apply org.locationtech.jts.geom.Point.getX polyCentroid.getX()
606 5665 27926 - 27963 Apply scala.Double.- gh1.getPoint.getX().-(polyCentroid.getX())
606 5666 27985 - 28002 Apply org.locationtech.jts.geom.Point.getY polyCentroid.getY()
606 5667 27965 - 28002 Apply scala.Double.- gh1.getPoint.getY().-(polyCentroid.getY())
606 5668 27915 - 28003 Apply java.lang.Math.hypot java.lang.Math.hypot(gh1.getPoint.getX().-(polyCentroid.getX()), gh1.getPoint.getY().-(polyCentroid.getY()))
607 5669 28019 - 28019 Select scala.Tuple2._1 x$6._1
607 5670 28031 - 28031 Select scala.Tuple2._2 x$6._2
611 5671 28143 - 28172 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.considerCandidate considerCandidate(firstChild)
614 5672 28286 - 28311 Select scala.collection.TraversableLike.headOption firstChildList.headOption
614 5678 28282 - 28282 TypeApply scala.collection.Seq.canBuildFrom collection.this.Seq.canBuildFrom[String]
614 5679 28267 - 28503 ApplyToImplicitArgs scala.collection.TraversableLike.++ firstChildList.++[String, Seq[String]](firstChildList.headOption match { case (value: String)Some[String]((bitStr @ _)) if bitStr.length().<=(minBits) => scala.collection.immutable.Nil case _ => considerCandidate(secondChild) })(collection.this.Seq.canBuildFrom[String])
615 5673 28353 - 28377 Apply scala.Int.<= bitStr.length().<=(minBits)
615 5674 28381 - 28384 Select scala.collection.immutable.Nil scala.collection.immutable.Nil
615 5675 28381 - 28384 Block scala.collection.immutable.Nil scala.collection.immutable.Nil
617 5676 28460 - 28490 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.considerCandidate considerCandidate(secondChild)
617 5677 28460 - 28490 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.considerCandidate considerCandidate(secondChild)
619 5681 28519 - 28522 Select scala.collection.immutable.Nil scala.collection.immutable.Nil
619 5682 28519 - 28522 Block scala.collection.immutable.Nil scala.collection.immutable.Nil
624 5690 28607 - 28744 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.apply BitPrefixes.apply(if (ghMBR.prec.<=(maxBits)) considerCandidate(ghMBR) else scala.collection.Seq.apply[String](scala.Predef.augmentString(scala.Predef.augmentString(ghMBR.toBinaryString).drop(minBits)).take(usedBits)))
625 5684 28630 - 28651 Apply scala.Int.<= ghMBR.prec.<=(maxBits)
625 5685 28653 - 28677 Apply org.locationtech.geomesa.utils.geohash.GeohashUtils.considerCandidate considerCandidate(ghMBR)
625 5686 28653 - 28677 Block org.locationtech.geomesa.utils.geohash.GeohashUtils.considerCandidate considerCandidate(ghMBR)
626 5687 28693 - 28742 Apply scala.collection.IndexedSeqOptimized.take scala.Predef.augmentString(scala.Predef.augmentString(ghMBR.toBinaryString).drop(minBits)).take(usedBits)
626 5688 28689 - 28743 Apply scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[String](scala.Predef.augmentString(scala.Predef.augmentString(ghMBR.toBinaryString).drop(minBits)).take(usedBits))
626 5689 28689 - 28743 Block scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[String](scala.Predef.augmentString(scala.Predef.augmentString(ghMBR.toBinaryString).drop(minBits)).take(usedBits))
629 5691 28777 - 28799 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.overflowed bitPrefixes.overflowed
629 5692 28801 - 29050 Throw <nosymbol> throw new java.lang.IllegalStateException("Bit prefixes overflowed while calculating unique Geohash substrings in polygon using the following parameters: ".+(scala.StringContext.apply("\\nGeometry: ", " \\nOffset: ", " \\nLength: ", " \\nMax Keys in List: ", "").s(geom, offset, length, MAX_KEYS_IN_LIST)))
629 5693 28801 - 29050 Block <nosymbol> throw new java.lang.IllegalStateException("Bit prefixes overflowed while calculating unique Geohash substrings in polygon using the following parameters: ".+(scala.StringContext.apply("\\nGeometry: ", " \\nOffset: ", " \\nLength: ", " \\nMax Keys in List: ", "").s(geom, offset, length, MAX_KEYS_IN_LIST)))
629 5694 28773 - 28773 Literal <nosymbol> ()
629 5695 28773 - 28773 Block <nosymbol> ()
634 5696 29188 - 29205 Select org.locationtech.geomesa.utils.geohash.GeohashUtils.BitPrefixes.toSeq bitPrefixes.toSeq
639 5697 29380 - 29403 Apply scala.Int.< unDotted.size.<(maxKeys)
639 5705 29405 - 29685 Block <nosymbol> { val keepers: List[String] = GeohashUtils.this.getGeohashStringDottingIterator(unDotted, MAX_KEYS_IN_LIST).take(MAX_KEYS_IN_LIST.+(1)).toList; if (keepers.size.<=(MAX_KEYS_IN_LIST)) keepers.toSeq else scala.collection.Seq.apply[Nothing]() }
639 5708 29376 - 29696 If <nosymbol> if (unDotted.size.<(maxKeys)) { val keepers: List[String] = GeohashUtils.this.getGeohashStringDottingIterator(unDotted, MAX_KEYS_IN_LIST).take(MAX_KEYS_IN_LIST.+(1)).toList; if (keepers.size.<=(MAX_KEYS_IN_LIST)) keepers.toSeq else scala.collection.Seq.apply[Nothing]() } else scala.collection.Seq.apply[Nothing]()
642 5698 29578 - 29598 Apply scala.Int.+ MAX_KEYS_IN_LIST.+(1)
642 5699 29502 - 29606 Select scala.collection.TraversableOnce.toList GeohashUtils.this.getGeohashStringDottingIterator(unDotted, MAX_KEYS_IN_LIST).take(MAX_KEYS_IN_LIST.+(1)).toList
643 5700 29619 - 29651 Apply scala.Int.<= keepers.size.<=(MAX_KEYS_IN_LIST)
643 5701 29653 - 29666 Select scala.collection.immutable.Seq.toSeq keepers.toSeq
643 5702 29653 - 29666 Block scala.collection.immutable.Seq.toSeq keepers.toSeq
643 5703 29672 - 29677 Apply scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[Nothing]()
643 5704 29672 - 29677 Block scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[Nothing]()
644 5706 29691 - 29696 Apply scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[Nothing]()
644 5707 29691 - 29696 Block scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[Nothing]()
645 5709 29708 - 29716 Ident org.locationtech.geomesa.utils.geohash.GeohashUtils.unDotted unDotted