Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
V
vectortile
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
WANDER
vectortile
Commits
26192e5c
Commit
26192e5c
authored
2 years ago
by
Knuiman, Bart
Browse files
Options
Downloads
Patches
Plain Diff
big wip
parent
becf3934
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Runtime/VectorTile.cs
+144
-23
144 additions, 23 deletions
Runtime/VectorTile.cs
with
144 additions
and
23 deletions
Runtime/VectorTile.cs
+
144
−
23
View file @
26192e5c
...
@@ -2,16 +2,58 @@ using Mapbox.Vector.Tile;
...
@@ -2,16 +2,58 @@ using Mapbox.Vector.Tile;
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.IO
;
using
System.Linq
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
UnityEditor
;
using
UnityEngine
;
using
UnityEngine
;
using
UnityEngine.Networking
;
using
UnityEngine.Networking
;
using
static
Wander
.
Easing
;
namespace
Wander
namespace
Wander
{
{
// Always multiple of 3. Each 3 form a triangle.
// Always multiple of 3. Each 3 form a triangle.
public
struct
TriangulatedPolygon
public
class
TriangulatedPolygon
{
{
public
List
<
Vector2
>
vertices
;
public
List
<
Vector2
>
vertices
;
public
List
<
Vector2
>
mins
;
public
List
<
Vector2
>
maxs
;
public
List
<
float
>
denoms
;
public
void
OptimizeForIsPointInTriangle
()
{
if
(
vertices
==
null
)
return
;
// Non poly layers have this.
mins
=
new
List
<
Vector2
>(
vertices
.
Count
/
3
);
maxs
=
new
List
<
Vector2
>(
vertices
.
Count
/
3
);
denoms
=
new
List
<
float
>(
vertices
.
Count
/
3
);
for
(
int
i
=
0
;
i
<
vertices
.
Count
;
i
+=
3
)
{
float
minx
=
float
.
MaxValue
;
float
miny
=
float
.
MaxValue
;
if
(
vertices
[
i
+
0
].
x
<
minx
)
minx
=
vertices
[
i
].
x
;
if
(
vertices
[
i
+
0
].
y
<
miny
)
miny
=
vertices
[
i
].
y
;
if
(
vertices
[
i
+
1
].
x
<
minx
)
minx
=
vertices
[
i
+
1
].
x
;
if
(
vertices
[
i
+
1
].
y
<
miny
)
miny
=
vertices
[
i
+
1
].
y
;
if
(
vertices
[
i
+
2
].
x
<
minx
)
minx
=
vertices
[
i
+
2
].
x
;
if
(
vertices
[
i
+
2
].
y
<
miny
)
miny
=
vertices
[
i
+
2
].
y
;
mins
.
Add
(
new
Vector2
(
minx
,
miny
)
);
float
maxx
=
float
.
MinValue
;
float
maxy
=
float
.
MinValue
;
if
(
vertices
[
i
+
0
].
x
>
maxx
)
maxx
=
vertices
[
i
].
x
;
if
(
vertices
[
i
+
0
].
y
>
maxy
)
maxy
=
vertices
[
i
].
y
;
if
(
vertices
[
i
+
1
].
x
>
maxx
)
maxx
=
vertices
[
i
+
1
].
x
;
if
(
vertices
[
i
+
1
].
y
>
maxy
)
maxy
=
vertices
[
i
+
1
].
y
;
if
(
vertices
[
i
+
2
].
x
>
maxx
)
maxx
=
vertices
[
i
+
2
].
x
;
if
(
vertices
[
i
+
2
].
y
>
maxy
)
maxy
=
vertices
[
i
+
2
].
y
;
maxs
.
Add
(
new
Vector2
(
maxx
,
maxy
)
);
// float denominator = ((vertex2.y - vertex3.y) * (vertex1.x - vertex3.x) + (vertex3.x - vertex2.x) * (vertex1.y - vertex3.y));
float
denominator
=
((
vertices
[
i
+
1
].
y
-
vertices
[
i
+
2
].
y
)
*
(
vertices
[
i
].
x
-
vertices
[
i
+
2
].
x
)
+
(
vertices
[
i
+
2
].
x
-
vertices
[
i
+
1
].
x
)
*
(
vertices
[
i
].
y
-
vertices
[
i
+
2
].
y
));
denoms
.
Add
(
1.0f
/
denominator
);
}
}
}
}
public
class
VectorTile
public
class
VectorTile
...
@@ -83,8 +125,11 @@ namespace Wander
...
@@ -83,8 +125,11 @@ namespace Wander
var
polygons
=
new
List
<
TriangulatedPolygon
>();
var
polygons
=
new
List
<
TriangulatedPolygon
>();
for
(
int
j
=
0
;
j
<
features
.
Count
;
j
++)
for
(
int
j
=
0
;
j
<
features
.
Count
;
j
++)
{
{
polygons
.
Add
(
new
TriangulatedPolygon
()
);
// Add empty to ensure list(layer) of lists(features) match.
if
(
features
[
j
].
GeometryType
!=
Tile
.
GeomType
.
Polygon
)
if
(
features
[
j
].
GeometryType
!=
Tile
.
GeomType
.
Polygon
)
{
continue
;
continue
;
}
vertices
.
Clear
();
vertices
.
Clear
();
holeIndices
.
Clear
();
holeIndices
.
Clear
();
var
rings
=
features
[
j
].
Geometry
;
var
rings
=
features
[
j
].
Geometry
;
...
@@ -112,7 +157,7 @@ namespace Wander
...
@@ -112,7 +157,7 @@ namespace Wander
double
y
=
vertices
[
indices
[
k
]*
2
+
1
];
double
y
=
vertices
[
indices
[
k
]*
2
+
1
];
poly
.
vertices
.
Add
(
new
Vector2
(
(
float
)
x
,
(
float
)
y
)
);
poly
.
vertices
.
Add
(
new
Vector2
(
(
float
)
x
,
(
float
)
y
)
);
}
}
polygons
.
Add
(
poly
)
;
polygons
[
polygons
.
Count
-
1
]
=
poly
;
Debug
.
Assert
(
poly
.
vertices
.
Count
%
3
==
0
);
Debug
.
Assert
(
poly
.
vertices
.
Count
%
3
==
0
);
}
}
catch
(
Exception
)
catch
(
Exception
)
...
@@ -126,20 +171,32 @@ namespace Wander
...
@@ -126,20 +171,32 @@ namespace Wander
return
numFailedPolys
;
return
numFailedPolys
;
}
}
public
void
OptimizeForPointIsInsideTriangle
()
{
for
(
int
i
=
0
;
i
<
polygonLayers
.
Count
;
i
++)
for
(
int
j
=
0
;
j
<
polygonLayers
[
i
].
Count
;
j
++)
polygonLayers
[
i
][
j
].
OptimizeForIsPointInTriangle
();
}
// Calls callback(x, y, channel) for each raster position (256 channels) where each value represents a single channel.
// Calls callback(x, y, channel) for each raster position (256 channels) where each value represents a single channel.
// If no polygon was hit, 255 is called.
// If no polygon was hit, 255 is called.
// If polygon was hit, but no feature was matched, 254 is called.
// If polygon was hit, but no feature was matched, 254 is called.
public
void
RenderToTextureSingle
(
int
width
,
int
height
,
string
attributeKeyMatch
,
List
<
List
<
string
>>
layerNamesList
,
Func
<
int
,
int
,
byte
,
bool
>
callback
)
// Returns a list of failed to match pixels. This can be due to geometry not exactly matching or a layer not being found.
public
List
<
Vector3Int
>
RenderToTextureSingle
(
int
width
,
int
height
,
List
<
string
>
matchingAttribKeys
,
List
<
List
<
string
>>
layerNamesList
,
Func
<
int
,
int
,
byte
,
bool
>
callback
)
{
{
Debug
.
Assert
(
triangulated
,
"First call Triangulate."
);
Debug
.
Assert
(
triangulated
,
"First call Triangulate."
);
Debug
.
Assert
(
layerNamesList
.
Count
<
254
,
"254 and 255 are reserved for no hit or no match."
);
Debug
.
Assert
(
layerNamesList
.
Count
<
254
,
"254 and 255 are reserved for no hit or no match."
);
bool
cancel
=
false
;
// First match layers to layer names.
// First match layers to layer names.
bool
cancel
=
false
;
List
<
Vector3Int
>
failedPixels
=
new
List
<
Vector3Int
>();
for
(
int
l
=
0
;
l
<
layers
.
Count
&&
!
cancel
;
l
++)
for
(
int
l
=
0
;
l
<
layers
.
Count
&&
!
cancel
;
l
++)
{
{
var
layer
=
layers
[
l
];
var
layer
=
layers
[
l
];
for
(
int
f
=
0
;
f
<
layer
.
VectorTileFeatures
.
Count
&&
!
cancel
;
f
++)
for
(
int
f
=
0
;
f
<
layer
.
VectorTileFeatures
.
Count
&&
!
cancel
;
f
++)
{
{
var
feature
=
layer
.
VectorTileFeatures
[
f
];
var
feature
=
layer
.
VectorTileFeatures
[
f
];
...
@@ -155,15 +212,35 @@ namespace Wander
...
@@ -155,15 +212,35 @@ namespace Wander
bool
matchingLayerFound
=
false
;
bool
matchingLayerFound
=
false
;
for
(
int
a
=
0
;
a
<
feature
.
Attributes
.
Count
&&
!
matchingLayerFound
;
a
++)
for
(
int
a
=
0
;
a
<
feature
.
Attributes
.
Count
&&
!
matchingLayerFound
;
a
++)
{
{
if
(
feature
.
Attributes
[
a
].
Key
!=
attributeKeyMatch
)
for
(
int
m
=
0
;
m
<
matchingAttribKeys
.
Count
&&
!
matchingLayerFound
;
m
++)
continue
;
{
if
(
feature
.
Attributes
[
a
].
Key
!=
matchingAttribKeys
[
m
])
string
function
=
feature
.
Attributes
[
a
].
Value
as
string
;
continue
;
string
function
=
feature
.
Attributes
[
a
].
Value
as
string
;
for
(
int
layerIdx
=
0
;
layerIdx
<
layerNamesList
.
Count
&&
!
matchingLayerFound
;
layerIdx
++)
{
for
(
int
layerNameIdx
=
0
;
layerNameIdx
<
layerNamesList
[
layerIdx
].
Count
;
layerNameIdx
++)
{
if
(
function
.
Contains
(
layerNamesList
[
layerIdx
][
layerNameIdx
]
))
{
feature
.
SelectedLayerIdx
=
layerIdx
;
matchingLayerFound
=
true
;
break
;
}
}
}
}
}
// try Layer.name
if
(!
matchingLayerFound
)
{
for
(
int
layerIdx
=
0
;
layerIdx
<
layerNamesList
.
Count
&&
!
matchingLayerFound
;
layerIdx
++)
for
(
int
layerIdx
=
0
;
layerIdx
<
layerNamesList
.
Count
&&
!
matchingLayerFound
;
layerIdx
++)
{
{
for
(
int
layerNameIdx
=
0
;
layerNameIdx
<
layerNamesList
[
layerIdx
].
Count
;
layerNameIdx
++)
for
(
int
layerNameIdx
=
0
;
layerNameIdx
<
layerNamesList
[
layerIdx
].
Count
;
layerNameIdx
++)
{
{
if
(
function
.
Contains
(
layerNamesList
[
layerIdx
][
layerNameIdx
]
))
if
(
layer
.
Name
.
Contains
(
layerNamesList
[
layerIdx
][
layerNameIdx
]
))
{
{
feature
.
SelectedLayerIdx
=
layerIdx
;
feature
.
SelectedLayerIdx
=
layerIdx
;
matchingLayerFound
=
true
;
matchingLayerFound
=
true
;
...
@@ -175,44 +252,88 @@ namespace Wander
...
@@ -175,44 +252,88 @@ namespace Wander
}
}
}
}
Debug
.
Assert
(
width
==
height
,
"Must be square images."
);
// For each layer, for each pixel, now check triangle intersections.
// For each layer, for each pixel, now check triangle intersections.
for
(
int
l
=
0
;
l
<
layers
.
Count
&&
!
cancel
;
l
++)
for
(
int
l
=
0
;
l
<
layers
.
Count
&&
!
cancel
;
l
++)
{
{
var
layer
=
layers
[
l
];
var
layer
=
layers
[
l
];
float
fx
=
(
float
)
layer
.
Extent
/
width
;
TriangulatedPolygon
cachedPoly
=
default
;
int
cachedVtxIdx
=
-
1
;
int
cachedTriIdx
=
-
1
;
byte
cachedPixel
=
0
;
for
(
int
y
=
0
;
y
<
height
&&
!
cancel
;
y
++)
for
(
int
y
=
0
;
y
<
height
&&
!
cancel
;
y
++)
{
{
for
(
int
x
=
0
;
x
<
width
&&
!
cancel
;
x
++)
for
(
int
x
=
0
;
x
<
width
&&
!
cancel
;
x
++)
{
{
Vector2
p
=
new
Vector2
(
x
,
y
);
Vector2
p
=
new
Vector2
(
fx
*
x
+
0.5f
*
fx
,
fx
*
y
+
0.5f
*
fx
);
bool
hit
=
false
;
for
(
int
f
=
0
;
f
<
layer
.
VectorTileFeatures
.
Count
&&
!
cancel
;
f
++)
// First try cache, quite often adjacent pixels will hit the same triangle.
if
(
cachedVtxIdx
!=-
1
)
{
var
vertices
=
cachedPoly
.
vertices
;
var
denoms
=
cachedPoly
.
denoms
;
var
mins
=
cachedPoly
.
mins
;
var
maxs
=
cachedPoly
.
maxs
;
if
(!(
p
.
x
<
mins
[
cachedTriIdx
].
x
||
p
.
x
>
maxs
[
cachedTriIdx
].
x
)
&&
!(
p
.
y
<
mins
[
cachedTriIdx
].
y
||
p
.
y
>
maxs
[
cachedTriIdx
].
y
))
{
hit
=
GeomUtil
.
PointIsInsideTriangle2
(
p
,
vertices
[
cachedVtxIdx
],
vertices
[
cachedVtxIdx
+
1
],
vertices
[
cachedVtxIdx
+
2
],
denoms
[
cachedTriIdx
]
);
if
(
hit
)
{
cancel
=
callback
(
x
,
y
,
cachedPixel
);
// If SelectedLayerIdx did not match, it was set to 254.
continue
;
// Pass from cache, continue to next pixel.
}
}
}
// Must check all triangles, no cache or was no hit with cache.
for
(
int
f
=
0
;
f
<
layer
.
VectorTileFeatures
.
Count
;
f
++)
{
{
var
feature
=
layer
.
VectorTileFeatures
[
f
];
var
feature
=
layer
.
VectorTileFeatures
[
f
];
if
(
feature
.
GeometryType
!=
Tile
.
GeomType
.
Polygon
)
if
(
feature
.
GeometryType
!=
Tile
.
GeomType
.
Polygon
)
continue
;
continue
;
var
triangles
=
polygonLayers
[
l
][
f
].
vertices
;
var
polygons
=
polygonLayers
[
l
][
f
];
bool
hit
=
false
;
if
(
polygons
.
vertices
.
Count
==
0
)
for
(
int
i
=
0
;
i
<
triangles
.
Count
&&
!
cancel
;
i
+=
3
)
continue
;
cachedVtxIdx
=
-
1
;
cachedPoly
=
polygonLayers
[
l
][
f
];
var
mins
=
cachedPoly
.
mins
;
var
maxs
=
cachedPoly
.
maxs
;
var
denoms
=
cachedPoly
.
denoms
;
var
vertices
=
cachedPoly
.
vertices
;
for
(
int
vIdx
=
0
,
triIdx
=
0
;
vIdx
<
vertices
.
Count
;
vIdx
+=
3
,
triIdx
++)
{
{
hit
=
GeomUtil
.
PointIsInsideTriangle
(
p
,
triangles
[
i
],
triangles
[
i
+
1
],
triangles
[
i
+
2
]
);
if
(
p
.
x
<
mins
[
triIdx
].
x
||
p
.
x
>
maxs
[
triIdx
].
x
)
continue
;
if
(
p
.
y
<
mins
[
triIdx
].
y
||
p
.
y
>
maxs
[
triIdx
].
y
)
continue
;
hit
=
GeomUtil
.
PointIsInsideTriangle2
(
p
,
vertices
[
vIdx
],
vertices
[
vIdx
+
1
],
vertices
[
vIdx
+
2
],
denoms
[
triIdx
]
);
if
(
hit
)
if
(
hit
)
{
{
cancel
=
callback
(
x
,
y
,
(
byte
)
feature
.
SelectedLayerIdx
);
// If SelectedLayerIdx did not match, it was set to 254.
cachedTriIdx
=
triIdx
;
cachedVtxIdx
=
vIdx
;
cachedPixel
=
(
byte
)
feature
.
SelectedLayerIdx
;
cancel
=
callback
(
x
,
y
,
cachedPixel
);
break
;
break
;
}
}
}
}
if
(!
hit
)
if
(
hit
)
break
;
{
}
callback
(
x
,
y
,
255
);
// no hit
}
if
(
!
hit
)
{
failedPixels
.
Add
(
new
Vector3Int
(
x
,
y
,
255
)
);
}
}
}
}
}
}
}
}
return
failedPixels
;
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment