Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
imagej-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
imagej-elphel
Commits
ab99e29d
Commit
ab99e29d
authored
Sep 13, 2022
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Created consolidated texture clusters
parent
ca08b513
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
130 additions
and
20 deletions
+130
-20
OpticalFlow.java
...ain/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
+4
-4
TexturedModel.java
...n/java/com/elphel/imagej/tileprocessor/TexturedModel.java
+86
-15
TileCluster.java
...ain/java/com/elphel/imagej/tileprocessor/TileCluster.java
+40
-1
No files found.
src/main/java/com/elphel/imagej/tileprocessor/OpticalFlow.java
View file @
ab99e29d
...
@@ -5380,10 +5380,10 @@ public class OpticalFlow {
...
@@ -5380,10 +5380,10 @@ public class OpticalFlow {
// debugging 3D model
// debugging 3D model
boolean
build_textured3d
=
true
;
boolean
build_textured3d
=
true
;
double
textured_disp_adiffo
=
0.3
;
double
textured_disp_adiffo
=
0.3
5
;
// 0.3
;
double
textured_disp_rdiffo
=
0.1
;
double
textured_disp_rdiffo
=
0.1
2
;
// 0.1
;
double
textured_disp_adiffd
=
0.4
;
double
textured_disp_adiffd
=
0.
6
;
// 0.
4;
double
textured_disp_rdiffd
=
0.12
;
double
textured_disp_rdiffd
=
0.1
8
;
// 0.1
2;
double
textured_disp_fof
=
1.5
;
double
textured_disp_fof
=
1.5
;
double
min_fg_bg
=
0.1
;
// NaN bg if difference from FG < this
double
min_fg_bg
=
0.1
;
// NaN bg if difference from FG < this
...
...
src/main/java/com/elphel/imagej/tileprocessor/TexturedModel.java
View file @
ab99e29d
...
@@ -35,10 +35,15 @@ public class TexturedModel {
...
@@ -35,10 +35,15 @@ public class TexturedModel {
public
static
final
int
threadsMax
=
100
;
// maximal number of threads to launch
public
static
final
int
threadsMax
=
100
;
// maximal number of threads to launch
public
static
final
int
TILE_EMPTY
=
0
;
public
static
final
int
TILE_EMPTY
=
0
;
public
static
final
int
TILE_BORDER
=
1
;
public
static
final
int
TILE_BORDER
=
1
;
public
static
final
int
TILE_CONFIRMED
=
2
;
public
static
final
int
TILE_BORDER_FLOAT
=
2
;
public
static
final
int
TILE_CANDIDATE
=
3
;
// not used
public
static
final
int
TILE_CONFIRMED
=
3
;
public
static
final
int
TILE_CANDIDATE
=
4
;
// not used
public
static
final
int
CLUSTER_NAN
=
-
2
;
// disparity is NaN
public
static
final
int
CLUSTER_NAN
=
-
2
;
// disparity is NaN
public
static
final
int
CLUSTER_UNASSIGNED
=
-
1
;
// not yet assinged (>=0 - cluster number)
public
static
final
int
CLUSTER_UNASSIGNED
=
-
1
;
// not yet assinged (>=0 - cluster number)
public
static
boolean
isBorder
(
int
d
)
{
return
(
d
==
TILE_BORDER
)
||
(
d
==
TILE_BORDER_FLOAT
);
}
public
static
TileCluster
[]
clusterizeFgBg
(
//
public
static
TileCluster
[]
clusterizeFgBg
(
//
final
int
tilesX
,
final
int
tilesX
,
...
@@ -73,7 +78,7 @@ public class TexturedModel {
...
@@ -73,7 +78,7 @@ public class TexturedModel {
}
}
}
}
final
int
dbg_tile
=
(
debugLevel
>
0
)?
977
:
-
1
;
final
int
dbg_tile
=
(
debugLevel
>
0
)?
2021
:-
1
;
//
977 : -1;
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
for
(
int
ithread
=
0
;
ithread
<
threads
.
length
;
ithread
++)
{
threads
[
ithread
]
=
new
Thread
()
{
threads
[
ithread
]
=
new
Thread
()
{
public
void
run
()
{
public
void
run
()
{
...
@@ -208,6 +213,7 @@ public class TexturedModel {
...
@@ -208,6 +213,7 @@ public class TexturedModel {
int
[]
tile_stat
=
new
int
[
tiles
];
int
[]
tile_stat
=
new
int
[
tiles
];
// int [] tile_layer = new int [tiles]; // just to know which layer was used for assigned tiles
// int [] tile_layer = new int [tiles]; // just to know which layer was used for assigned tiles
// int current_cluster = 0;
// int current_cluster = 0;
final
boolean
debug_index
=
debugLevel
>
0
;
while
(
true
)
{
while
(
true
)
{
// find remaining tile with maximal number of neighbors (usually 8) - this will require num_neibs update
// find remaining tile with maximal number of neighbors (usually 8) - this will require num_neibs update
...
@@ -232,6 +238,9 @@ public class TexturedModel {
...
@@ -232,6 +238,9 @@ public class TexturedModel {
}
}
}
}
}
}
if
(
best_tile
==
dbg_tile
)
{
System
.
out
.
println
(
"clusterizeFgBg().4: best_tile="
+
best_tile
);
}
tile_start
=
best_tile
;
// will start from this
tile_start
=
best_tile
;
// will start from this
if
(
nn
==
0
)
{
// no even single-tile clusters are left
if
(
nn
==
0
)
{
// no even single-tile clusters are left
break
;
// no more seeds for clusters
break
;
// no more seeds for clusters
...
@@ -250,23 +259,28 @@ public class TexturedModel {
...
@@ -250,23 +259,28 @@ public class TexturedModel {
boolean
confirm
=
false
;
boolean
confirm
=
false
;
disparity
[
tile
]
=
disparities
[
layer
][
tile
];
disparity
[
tile
]
=
disparities
[
layer
][
tile
];
if
(
tn
.
isBorder
(
tile
))
{
if
(
tn
.
isBorder
(
tile
))
{
tile_stat
[
tile
]
=
TILE_BORDER
;
tile_stat
[
tile
]
=
TILE_BORDER_FLOAT
;
// TILE_BORDER;
if
(
Double
.
isNaN
(
disparity
[
tile
]))
{
System
.
out
.
println
(
"clusterizeFgBg(): 4. Disparity is set NaN for tile "
+
tile
);
}
}
else
{
}
else
{
confirm
=
true
;
confirm
=
true
;
for
(
int
dir
=
0
;
dir
<
TileNeibs
.
DIRS
;
dir
++)
{
for
(
int
dir
=
0
;
dir
<
TileNeibs
.
DIRS
;
dir
++)
{
int
tile1
=
tn
.
getNeibIndex
(
tile
,
dir
);
// should always be > 0 here
int
tile1
=
tn
.
getNeibIndex
(
tile
,
dir
);
// should always be > 0 here
//is it a border tile or already confirmed one ?
//is it a border tile or already confirmed one ?
if
((
tile_stat
[
tile1
]
==
TILE_BORDER
)
||
(
tile_stat
[
tile1
]
==
TILE_CONFIRMED
)){
// if ((tile_stat[tile1] == TILE_BORDER) || (tile_stat[tile1] == TILE_CONFIRMED)){
if
(
isBorder
(
tile_stat
[
tile1
])
||
(
tile_stat
[
tile1
]
==
TILE_CONFIRMED
)){
double
mid_disp
=
Math
.
max
(
0.0
,
0.5
*(
disparities
[
layer
][
tile
]
+
disparity
[
tile1
]));
double
mid_disp
=
Math
.
max
(
0.0
,
0.5
*(
disparities
[
layer
][
tile
]
+
disparity
[
tile1
]));
double
max_disp_diff
=
((
dir
&
1
)
==
0
)
?
double
max_disp_diff
=
((
dir
&
1
)
==
0
)
?
(
disp_adiffo
+
mid_disp
*
disp_rdiffo
)
:
(
disp_adiffo
+
mid_disp
*
disp_rdiffo
)
:
(
disp_adiffd
+
mid_disp
*
disp_rdiffd
);
(
disp_adiffd
+
mid_disp
*
disp_rdiffd
);
max_disp_diff
*=
(
tile_stat
[
tile1
]
==
TILE_BORDER
)?
disp_border
:
disp_fof
;
// max_disp_diff *= (tile_stat[tile1] == TILE_BORDER)? disp_border : disp_fof;
max_disp_diff
*=
isBorder
(
tile_stat
[
tile1
])?
disp_border
:
disp_fof
;
if
((
Math
.
abs
(
disparities
[
layer
][
tile
]
-
disparity
[
tile1
])/
max_disp_diff
)
>
1.0
){
if
((
Math
.
abs
(
disparities
[
layer
][
tile
]
-
disparity
[
tile1
])/
max_disp_diff
)
>
1.0
){
confirm
=
false
;
// too large diff
confirm
=
false
;
// too large diff
// make it a border tile, but keep disparity
// make it a border tile, but keep disparity
// disparity[tile] = disparities[layer][tile];
// disparity[tile] = disparities[layer][tile];
tile_stat
[
tile
]
=
TILE_BORDER
;
tile_stat
[
tile
]
=
TILE_BORDER
_FLOAT
;
// TILE_BORDER
;
break
;
break
;
}
}
}
}
...
@@ -277,6 +291,9 @@ public class TexturedModel {
...
@@ -277,6 +291,9 @@ public class TexturedModel {
System
.
out
.
println
(
"Confirmed tile "
+
tile
+
" (x="
+(
tile
%
tilesX
)+
", y="
+(
tile
/
tilesX
)+
") -> "
+
tile_stat
[
tile
]);
System
.
out
.
println
(
"Confirmed tile "
+
tile
+
" (x="
+(
tile
%
tilesX
)+
", y="
+(
tile
/
tilesX
)+
") -> "
+
tile_stat
[
tile
]);
}
}
tile_stat
[
tile
]
=
TILE_CONFIRMED
;
tile_stat
[
tile
]
=
TILE_CONFIRMED
;
if
(
Double
.
isNaN
(
disparity
[
tile
]))
{
System
.
out
.
println
(
"clusterizeFgBg(): 5. Disparity is set NaN for tile "
+
tile
);
}
ncluster
[
tile
][
layer
]
=
cluster_list
.
size
();
// current cluster number - Mark as assigned
ncluster
[
tile
][
layer
]
=
cluster_list
.
size
();
// current cluster number - Mark as assigned
// tile_layer[tile] = layer;
// tile_layer[tile] = layer;
// right here - update number of neighbors for used tile
// right here - update number of neighbors for used tile
...
@@ -319,15 +336,24 @@ public class TexturedModel {
...
@@ -319,15 +336,24 @@ public class TexturedModel {
}
}
}
}
if
(
layer_assigned
>=
0
)
{
// already assigned to some cluster that was split
if
(
layer_assigned
>=
0
)
{
// already assigned to some cluster that was split
tile_stat
[
tile1
]
=
TILE_BORDER
;
tile_stat
[
tile1
]
=
TILE_BORDER
;
// here - fixed disparity, not float
disparity
[
tile1
]
=
disparities
[
layer_assigned
][
tile
];
// Use interrupted cluster disparity
disparity
[
tile1
]
=
disparities
[
layer_assigned
][
tile1
];
// [tile]; // Use interrupted cluster disparity
if
(
Double
.
isNaN
(
disparity
[
tile1
]))
{
System
.
out
.
println
(
"clusterizeFgBg(): *1. Disparity is set NaN for tile "
+
tile1
);
}
}
else
if
((
layer1
<
0
)
||
(
connections
[
tile
][
layer
][
dir
][
layer1
]
>
1.0
))
{
// no connections in this direction - add border using same disparity as this tile
}
else
if
((
layer1
<
0
)
||
(
connections
[
tile
][
layer
][
dir
][
layer1
]
>
1.0
))
{
// no connections in this direction - add border using same disparity as this tile
if
(
tile_stat
[
tile1
]
==
TILE_EMPTY
)
{
// not yet set (otherwise keep)
if
(
tile_stat
[
tile1
]
==
TILE_EMPTY
)
{
// not yet set (otherwise keep)
tile_stat
[
tile1
]
=
TILE_BORDER
;
tile_stat
[
tile1
]
=
TILE_BORDER
_FLOAT
;
//TILE_BORDER
;
disparity
[
tile1
]
=
disparity
[
tile
];
disparity
[
tile1
]
=
disparity
[
tile
];
if
(
Double
.
isNaN
(
disparity
[
tile1
]))
{
System
.
out
.
println
(
"clusterizeFgBg(): 2. Disparity is set NaN for tile "
+
tile1
);
}
}
}
}
else
{
// connection exists, add tile1/layer1 as a candidate to the list
}
else
{
// connection exists, add tile1/layer1 as a candidate to the list
tile_stat
[
tile1
]
=
TILE_CANDIDATE
;
// to avoid suggesting the same tile multiple times
tile_stat
[
tile1
]
=
TILE_CANDIDATE
;
// to avoid suggesting the same tile multiple times
if
(
Double
.
isNaN
(
disparity
[
tile1
]))
{
System
.
out
.
println
(
"clusterizeFgBg(): *3. Disparity is set NaN for tile "
+
tile1
);
}
tile_layer_list
.
add
(
new
Point
(
tile1
,
layer1
));
tile_layer_list
.
add
(
new
Point
(
tile1
,
layer1
));
}
}
}
}
...
@@ -354,17 +380,41 @@ public class TexturedModel {
...
@@ -354,17 +380,41 @@ public class TexturedModel {
Rectangle
bounds
=
new
Rectangle
(
min_x
,
min_y
,
width
,
height
);
Rectangle
bounds
=
new
Rectangle
(
min_x
,
min_y
,
width
,
height
);
double
[]
disparity_crop
=
new
double
[
width
*
height
];
double
[]
disparity_crop
=
new
double
[
width
*
height
];
boolean
[]
border_crop
=
new
boolean
[
width
*
height
];
boolean
[]
border_crop
=
new
boolean
[
width
*
height
];
double
[]
wdir
=
{
1.0
,
0.7
,
1.0
,
0.7
,
1.0
,
0.7
,
1.0
,
0.7
};
// weights for directions
for
(
int
dty
=
0
;
dty
<
height
;
dty
++)
{
for
(
int
dty
=
0
;
dty
<
height
;
dty
++)
{
int
ty
=
min_y
+
dty
;
int
ty
=
min_y
+
dty
;
for
(
int
dtx
=
0
;
dtx
<
width
;
dtx
++)
{
for
(
int
dtx
=
0
;
dtx
<
width
;
dtx
++)
{
int
tdest
=
dty
*
width
+
dtx
;
int
tdest
=
dty
*
width
+
dtx
;
int
tsrc
=
ty
*
tilesX
+
min_x
+
dtx
;
int
tsrc
=
ty
*
tilesX
+
min_x
+
dtx
;
border_crop
[
tdest
]
=
tile_stat
[
tsrc
]
==
TILE_BORDER
;
// replace disparity for the floating border tiles with the weighted average of non-floating
if
(
tile_stat
[
tsrc
]
==
TILE_BORDER_FLOAT
)
{
// average disparity from non-float defined tiles
// TODO: use best plane fit (for gradients)
// TODO: remove some "inner" border tiles?
double
sw
=
0.0
;
double
swd
=
0.0
;
for
(
int
dir
=
0
;
dir
<
TileNeibs
.
DIRS
;
dir
++)
{
int
tile1
=
tn
.
getNeibIndex
(
tsrc
,
dir
);
// should always be > 0 here
if
(
tile1
>=
0
)
{
if
((
tile_stat
[
tile1
]
==
TILE_BORDER
)
||
(
tile_stat
[
tile1
]
==
TILE_CONFIRMED
))
{
sw
+=
wdir
[
dir
];
swd
+=
wdir
[
dir
]
*
disparity
[
tile1
];
}
}
}
if
(
sw
>
0.0
)
{
disparity
[
tsrc
]
=
swd
/
sw
;
}
}
border_crop
[
tdest
]
=
isBorder
(
tile_stat
[
tsrc
]);
// == TILE_BORDER;
disparity_crop
[
tdest
]
=
(
tile_stat
[
tsrc
]
==
TILE_EMPTY
)
?
Double
.
NaN
:
disparity
[
tsrc
];
disparity_crop
[
tdest
]
=
(
tile_stat
[
tsrc
]
==
TILE_EMPTY
)
?
Double
.
NaN
:
disparity
[
tsrc
];
}
}
}
}
TileCluster
tileCluster
=
(
new
TileCluster
(
bounds
,
border_crop
,
disparity_crop
));
TileCluster
tileCluster
=
(
new
TileCluster
(
bounds
,
(
debug_index
?
cluster_list
.
size
():
-
1
),
border_crop
,
disparity_crop
));
cluster_list
.
add
(
tileCluster
);
cluster_list
.
add
(
tileCluster
);
// update
// update
...
@@ -410,7 +460,11 @@ public class TexturedModel {
...
@@ -410,7 +460,11 @@ public class TexturedModel {
TileCluster
[]
consolidated_clusters
=
new
TileCluster
[
this_combo
];
TileCluster
[]
consolidated_clusters
=
new
TileCluster
[
this_combo
];
Rectangle
full_tiles
=
new
Rectangle
(
0
,
0
,
tilesX
,
tilesY
);
Rectangle
full_tiles
=
new
Rectangle
(
0
,
0
,
tilesX
,
tilesY
);
for
(
int
i
=
0
;
i
<
this_combo
;
i
++)
{
for
(
int
i
=
0
;
i
<
this_combo
;
i
++)
{
consolidated_clusters
[
i
]
=
new
TileCluster
(
full_tiles
,
null
,
null
);
consolidated_clusters
[
i
]
=
new
TileCluster
(
full_tiles
,
(
debug_index
?
0
:-
1
),
null
,
null
);
}
}
for
(
int
i
=
0
;
i
<
comb_clusters
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
comb_clusters
.
length
;
i
++)
{
consolidated_clusters
[
comb_clusters
[
i
]].
add
(
cluster_list
.
get
(
i
));
consolidated_clusters
[
comb_clusters
[
i
]].
add
(
cluster_list
.
get
(
i
));
...
@@ -419,10 +473,18 @@ public class TexturedModel {
...
@@ -419,10 +473,18 @@ public class TexturedModel {
if
(
debugLevel
>
0
)
{
if
(
debugLevel
>
0
)
{
double
[][]
dbg_img
=
new
double
[
this_combo
][
tiles
];
double
[][]
dbg_img
=
new
double
[
this_combo
][
tiles
];
double
[][]
dbg_borders
=
new
double
[
this_combo
][
tiles
];
double
[][]
dbg_borders
=
new
double
[
this_combo
][
tiles
];
double
[][]
dbg_index
=
null
;
if
(
debug_index
)
{
dbg_index
=
new
double
[
this_combo
][
tiles
];
}
for
(
int
n
=
0
;
n
<
dbg_img
.
length
;
n
++)
{
for
(
int
n
=
0
;
n
<
dbg_img
.
length
;
n
++)
{
for
(
int
i
=
0
;
i
<
tiles
;
i
++)
{
for
(
int
i
=
0
;
i
<
tiles
;
i
++)
{
dbg_img
[
n
][
i
]
=
consolidated_clusters
[
n
].
getDisparity
()[
i
];
dbg_img
[
n
][
i
]
=
consolidated_clusters
[
n
].
getDisparity
()[
i
];
dbg_borders
[
n
][
i
]
=
consolidated_clusters
[
n
].
getBorder
()[
i
]?
1.0
:
0.0
;
dbg_borders
[
n
][
i
]
=
consolidated_clusters
[
n
].
getBorder
()[
i
]?
1.0
:
0.0
;
if
(
dbg_index
!=
null
)
{
double
d
=
consolidated_clusters
[
n
].
getClusterIndex
()[
i
];
dbg_index
[
n
][
i
]
=
(
d
>=
0
)?
d
:
Double
.
NaN
;
}
}
}
}
}
(
new
ShowDoubleFloatArrays
()).
showArrays
(
(
new
ShowDoubleFloatArrays
()).
showArrays
(
...
@@ -437,6 +499,15 @@ public class TexturedModel {
...
@@ -437,6 +499,15 @@ public class TexturedModel {
tilesY
,
tilesY
,
true
,
true
,
"cluster_borders"
);
"cluster_borders"
);
if
(
dbg_index
!=
null
)
{
(
new
ShowDoubleFloatArrays
()).
showArrays
(
dbg_index
,
tilesX
,
tilesY
,
true
,
"cluster_indices"
);
}
}
}
return
consolidated_clusters
;
return
consolidated_clusters
;
}
}
...
...
src/main/java/com/elphel/imagej/tileprocessor/TileCluster.java
View file @
ab99e29d
...
@@ -28,7 +28,9 @@ import java.util.Arrays;
...
@@ -28,7 +28,9 @@ import java.util.Arrays;
class
TileCluster
{
class
TileCluster
{
Rectangle
bounds
;
Rectangle
bounds
;
boolean
[]
border
;
boolean
[]
border
;
double
[]
disparity
;
double
[]
disparity
;
// all and only unused - NaN
int
[]
cluster_index
;
// for debug purposes, index of the source cluster
/*
public TileCluster (Rectangle bounds, boolean [] border, double [] disparity){
public TileCluster (Rectangle bounds, boolean [] border, double [] disparity){
this.bounds = bounds;
this.bounds = bounds;
if (border == null) {
if (border == null) {
...
@@ -41,9 +43,38 @@ class TileCluster{
...
@@ -41,9 +43,38 @@ class TileCluster{
}
}
this.disparity = disparity;
this.disparity = disparity;
}
}
*/
// to use cluster_index - set index >= 0, <0 - do not use.
public
TileCluster
(
Rectangle
bounds
,
int
index
,
// <0 to skip
boolean
[]
border
,
double
[]
disparity
){
this
.
bounds
=
bounds
;
if
(
index
>=
0
)
{
this
.
cluster_index
=
new
int
[
bounds
.
width
*
bounds
.
height
];
Arrays
.
fill
(
cluster_index
,
-
1
);
if
(
disparity
!=
null
)
{
for
(
int
i
=
0
;
i
<
cluster_index
.
length
;
i
++)
if
(!
Double
.
isNaN
(
disparity
[
i
])){
cluster_index
[
i
]
=
index
;
}
}
}
if
(
border
==
null
)
{
border
=
new
boolean
[
bounds
.
width
*
bounds
.
height
];
}
this
.
border
=
border
;
if
(
disparity
==
null
)
{
disparity
=
new
double
[
bounds
.
width
*
bounds
.
height
];
Arrays
.
fill
(
disparity
,
Double
.
NaN
);
}
this
.
disparity
=
disparity
;
}
public
Rectangle
getBounds
()
{
return
bounds
;}
public
Rectangle
getBounds
()
{
return
bounds
;}
public
boolean
[]
getBorder
()
{
return
border
;}
public
boolean
[]
getBorder
()
{
return
border
;}
public
double
[]
getDisparity
()
{
return
disparity
;}
public
double
[]
getDisparity
()
{
return
disparity
;}
public
int
[]
getClusterIndex
()
{
return
cluster_index
;}
/*
/*
public TileCluster combine (TileCluster tileCluster) {
public TileCluster combine (TileCluster tileCluster) {
TileCluster outer, inner;
TileCluster outer, inner;
...
@@ -97,6 +128,14 @@ class TileCluster{
...
@@ -97,6 +128,14 @@ class TileCluster{
disparity
,
disparity
,
dst_y
*
bounds
.
width
+
dst_x
,
dst_y
*
bounds
.
width
+
dst_x
,
tileCluster
.
bounds
.
width
);
tileCluster
.
bounds
.
width
);
if
((
cluster_index
!=
null
)
&&
(
tileCluster
.
cluster_index
!=
null
))
{
System
.
arraycopy
(
tileCluster
.
cluster_index
,
src_y
*
tileCluster
.
bounds
.
width
,
cluster_index
,
dst_y
*
bounds
.
width
+
dst_x
,
tileCluster
.
bounds
.
width
);
}
}
}
return
;
return
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment