Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
N
ng-smart3d
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张启明
ng-smart3d
Commits
8a4f2259
Commit
8a4f2259
authored
Jan 08, 2020
by
张启明
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
test: 添加模型编辑、拾取类,完善粒子特效、图层管理、模型剖切
parent
0bfc17a3
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
516 additions
and
67 deletions
+516
-67
app.component.css
src/app/app.component.css
+2
-0
app.component.html
src/app/app.component.html
+6
-2
app.component.ts
src/app/app.component.ts
+2
-1
app.module.ts
src/app/app.module.ts
+4
-0
index.ts
src/app/components/index.ts
+2
-0
layer-manager.component.css
src/app/components/layer-manager/layer-manager.component.css
+9
-0
layer-manager.component.html
...app/components/layer-manager/layer-manager.component.html
+40
-1
layer-manager.component.ts
src/app/components/layer-manager/layer-manager.component.ts
+112
-2
particle-effect.component.html
...components/particle-effect/particle-effect.component.html
+9
-3
particle-effect.component.ts
...p/components/particle-effect/particle-effect.component.ts
+23
-0
index.ts
src/app/components/pick/index.ts
+1
-0
pick.component.css
src/app/components/pick/pick.component.css
+0
-0
pick.component.html
src/app/components/pick/pick.component.html
+6
-0
pick.component.spec.ts
src/app/components/pick/pick.component.spec.ts
+25
-0
pick.component.ts
src/app/components/pick/pick.component.ts
+45
-0
tileset-clipping.component.ts
...components/tileset-clipping/tileset-clipping.component.ts
+11
-22
index.ts
src/app/components/tileset-editor/index.ts
+1
-0
tileset-editor.component.css
...pp/components/tileset-editor/tileset-editor.component.css
+0
-0
tileset-editor.component.html
...p/components/tileset-editor/tileset-editor.component.html
+5
-0
tileset-editor.component.spec.ts
...omponents/tileset-editor/tileset-editor.component.spec.ts
+25
-0
tileset-editor.component.ts
...app/components/tileset-editor/tileset-editor.component.ts
+82
-0
index.ts
src/app/services/index.ts
+0
-1
index.ts
src/app/services/layer-manager/index.ts
+0
-1
layer-manager.service.spec.ts
src/app/services/layer-manager/layer-manager.service.spec.ts
+0
-12
layer-manager.service.ts
src/app/services/layer-manager/layer-manager.service.ts
+0
-16
viewer.service.ts
src/app/services/viewer/viewer.service.ts
+105
-6
styles.css
src/styles.css
+1
-0
No files found.
src/app/app.component.css
View file @
8a4f2259
#container
{
position
:
relative
;
height
:
100vh
;
width
:
100vw
;
}
.widgets
{
...
...
src/app/app.component.html
View file @
8a4f2259
...
...
@@ -8,7 +8,11 @@
<app-underground></app-underground>
<app-soil-excavation></app-soil-excavation>
<app-particle-effect></app-particle-effect>
<app-tileset-clipping></app-tileset-clipping>
<app-layer-manager></app-layer-manager>
<div
style=
"border: 1px solid white; padding: 5px; margin: 5px;"
>
<div><app-layer-manager></app-layer-manager></div>
<div>
3D tiles 剖切:
<app-tileset-clipping></app-tileset-clipping></div>
<div>
3D tiles 位置编辑:
<app-tileset-editor></app-tileset-editor></div>
<app-pick></app-pick>
</div>
</div>
</div>
src/app/app.component.ts
View file @
8a4f2259
...
...
@@ -18,7 +18,8 @@ export class AppComponent implements OnInit {
this
.
viewer
=
this
.
viewerService
.
initViewer
(
'container'
,
{
sceneMode
:
smart3d
.
SceneMode
.
SCENE3D
,
scene3DOnly
:
true
,
terrainProvider
:
smart3d
.
TerrainManager
.
createWorldTerrain
(),
// terrainProvider: smart3d.TerrainManager.createWorldTerrain(),
baseMapMode
:
smart3d
.
BaseMapMode
.
ESRI
,
helper
:
false
,
});
}
...
...
src/app/app.module.ts
View file @
8a4f2259
...
...
@@ -14,6 +14,8 @@ import {
SoilExcavationComponent
,
ParticleEffectComponent
,
TilesetClippingComponent
,
TilesetEditorComponent
,
PickComponent
,
}
from
'./components'
;
@
NgModule
({
...
...
@@ -29,6 +31,8 @@ import {
SoilExcavationComponent
,
ParticleEffectComponent
,
TilesetClippingComponent
,
TilesetEditorComponent
,
PickComponent
,
],
imports
:
[
BrowserModule
,
...
...
src/app/components/index.ts
View file @
8a4f2259
...
...
@@ -8,3 +8,5 @@ export * from './underground';
export
*
from
'./soil-excavation'
;
export
*
from
'./particle-effect'
;
export
*
from
'./tileset-clipping'
;
export
*
from
'./tileset-editor'
;
export
*
from
'./pick'
;
src/app/components/layer-manager/layer-manager.component.css
View file @
8a4f2259
#modal
{
max-width
:
80vw
;
max-height
:
80vh
;
border
:
1px
solid
#333
;
border-radius
:
.3em
;
box-shadow
:
0
0
0
71vmax
rgba
(
0
,
0
,
0
,
.8
);
}
\ No newline at end of file
src/app/components/layer-manager/layer-manager.component.html
View file @
8a4f2259
<p>
layer-manager works!
</p>
<select
[(
ngModel
)]="
currentLayerName
"
(
ngModelChange
)="
handleCurrentLayerNameChange
()"
>
<option
*
ngFor=
"let layerStore of layersStore"
[
value
]="
layerStore
.
name
"
>
{{ layerStore.name }} —— {{ layerStore.type }}
</option>
</select>
<button
(
click
)="
locatingLayer
()"
>
定位到该图层
</button>
<button
(
click
)="
removeLayer
()"
>
删除该图层
</button>
<button
(
click
)="
toggleLayerShow
()"
>
显隐该图层
</button>
<button
(
click
)="
addLayer
()"
>
添加图层
</button>
<dialog
id=
"modal"
#
dialog
>
<form
method=
"dialog"
>
<p>
<label
for=
"layer-name"
>
图层名:
</label><input
id=
"layer-name"
type=
"text"
[(
ngModel
)]="
addLayerStore
.
name
"
name=
"name"
/>
</p>
<p>
<label
for=
"layer-url"
>
图层 URL:
</label><input
id=
"layer-url"
type=
"url"
[(
ngModel
)]="
addLayerStore
.
url
"
name=
"url"
/>
</p>
<p>
<label
for=
"layer-type"
>
图层类型:
</label>
<select
id=
"layer-type"
[(
ngModel
)]="
addLayerStore
.
type
"
name=
"type"
>
<option
[
value
]="
LayerTypeMode
.
MODEL
"
>
模型
</option>
<option
[
value
]="
LayerTypeMode
.
IMAGERY
"
>
倾斜摄影
</option>
<option
[
value
]="
LayerTypeMode
.
POINTCLOUD
"
>
点云
</option>
<option
[
value
]="
LayerTypeMode
.
TERRAIN
"
>
地形
</option>
<option
[
value
]="
LayerTypeMode
.
IMAGEDATA
"
>
地图影像
</option>
<option
[
value
]="
LayerTypeMode
.
PANORAMICIMAGE
"
>
全景影像
</option>
<option
[
value
]="
LayerTypeMode
.
VECTOR
"
>
矢量
</option>
<option
[
value
]="
LayerTypeMode
.
WMS
"
>
WMS服务
</option>
<option
[
value
]="
LayerTypeMode
.
WMTS
"
>
WMTS服务
</option>
</select>
</p>
<menu>
<button
(
click
)="
confirmAddLayer
('
canceled
')"
>
取消
</button>
<button
(
click
)="
confirmAddLayer
('
confirmed
')"
>
确定
</button>
</menu>
</form>
</dialog>
\ No newline at end of file
src/app/components/layer-manager/layer-manager.component.ts
View file @
8a4f2259
import
{
Component
,
OnInit
}
from
'@angular/core'
;
import
{
Component
,
OnInit
,
ViewChild
,
ElementRef
}
from
'@angular/core'
;
import
{
ViewerService
}
from
'src/app/services'
;
@
Component
({
selector
:
'app-layer-manager'
,
...
...
@@ -7,9 +8,118 @@ import { Component, OnInit } from '@angular/core';
})
export
class
LayerManagerComponent
implements
OnInit
{
constructor
()
{
}
public
layersStore
=
[
{
name
:
'黄石海事倾斜'
,
url
:
'http://172.16.126.125:8090/qlhtest/huangshihaishi/010202ban_qlh/tileset.json'
,
type
:
smart3d
.
LayerTypeMode
.
IMAGERY
},
{
name
:
'测绘大楼分层模型'
,
url
:
'http://www.south-smart.com/w3d-data/modeldata/nanfangcehuiBIM/NFCH0911/CHDLFC/tileset.json'
,
type
:
smart3d
.
LayerTypeMode
.
MODEL
},
{
name
:
'南昌林业点云服务'
,
url
:
'http://www.south-smart.com/w3d-data/modeldata/nanchanglinye/tileset.json'
,
type
:
smart3d
.
LayerTypeMode
.
POINTCLOUD
},
{
name
:
'UTM51DOM服务(WMTS)'
,
url
:
'http://172.16.10.221:8080/geoserver/gwc/service/wmts?layer=gwth:UTM51DOM'
,
type
:
smart3d
.
LayerTypeMode
.
WMTS
},
{
name
:
'甘肃联通植被控制点服务'
,
url
:
'http://www.south-smart.com/w3d-data/modeldata/gansuliantong/vector/zbpoint/zbpoint.json'
,
type
:
smart3d
.
LayerTypeMode
.
VECTOR
,
vectorStyle
:
new
smart3d
.
VectorStyle
({
fillColor
:
'#FF0000'
})
},
{
name
:
'甘肃联通其它道路服务'
,
url
:
'http://www.south-smart.com/w3d-data/modeldata/gansuliantong/vector/road_QT/road_QT.json'
,
type
:
smart3d
.
LayerTypeMode
.
VECTOR
,
vectorStyle
:
new
smart3d
.
VectorStyle
({
lineColor
:
'#FF0000'
,
lineWidth
:
5
})
}
];
public
currentLayerName
=
this
.
layersStore
.
length
>
0
?
this
.
layersStore
[
0
].
name
:
''
;
@
ViewChild
(
'dialog'
,
{
static
:
false
})
dialog
:
ElementRef
;
public
addLayerStore
=
{
url
:
''
,
name
:
''
,
type
:
''
,
};
public
LayerTypeMode
=
smart3d
.
LayerTypeMode
;
constructor
(
private
viewerService
:
ViewerService
,
)
{
}
ngOnInit
()
{
for
(
const
layerStore
of
this
.
layersStore
)
{
const
layer
=
new
smart3d
.
Layer
({
...
layerStore
,
});
this
.
viewerService
.
addLayer
(
layer
);
}
this
.
viewerService
.
currentLayerNameChange
.
emit
(
this
.
currentLayerName
);
}
/**
* 定位到当前图层,依赖于 this.currentLayerName
*/
locatingLayer
():
void
{
this
.
viewerService
.
flyToLayerByName
(
this
.
currentLayerName
);
}
addLayer
()
{
if
(
typeof
this
.
dialog
.
nativeElement
.
showModal
===
'function'
)
{
this
.
dialog
.
nativeElement
.
showModal
();
}
else
{
alert
(
'你的浏览器不支持 dialog API。'
);
}
}
confirmAddLayer
(
type
:
'canceled'
|
'confirmed'
)
{
if
(
type
===
'confirmed'
)
{
if
(
Object
.
values
(
this
.
addLayerStore
).
some
(
v
=>
v
===
''
))
{
alert
(
'图层名、图层 URL 或图层类型不能为空'
);
return
;
}
this
.
dialog
.
nativeElement
.
close
();
try
{
this
.
viewerService
.
addLayer
({
...
this
.
addLayerStore
});
this
.
layersStore
.
push
({
...
this
.
addLayerStore
});
}
catch
(
e
)
{
alert
(
e
.
message
);
}
}
else
if
(
type
===
'canceled'
)
{
this
.
dialog
.
nativeElement
.
close
();
}
}
removeLayer
()
{
this
.
viewerService
.
removeLayerByName
(
this
.
currentLayerName
);
const
layerIndex
=
this
.
layersStore
.
findIndex
(
layer
=>
layer
.
name
===
this
.
currentLayerName
);
this
.
layersStore
.
splice
(
layerIndex
,
1
);
}
toggleLayerShow
()
{
this
.
viewerService
.
toggleLayerShow
(
this
.
currentLayerName
);
}
handleCurrentLayerNameChange
():
void
{
this
.
viewerService
.
currentLayerNameChange
.
emit
(
this
.
currentLayerName
);
}
}
src/app/components/particle-effect/particle-effect.component.html
View file @
8a4f2259
<div>
<button
(
click
)="
enableParticleEffect
('
rain
')"
>
开启雨
</button>
<button
(
click
)="
rainEffect
?
disableEffect
('
rain
')
:
enableParticleEffect
('
rain
')"
>
{{ rainEffect ? '取消' : '开启' }}雨
</button>
<input
type=
"range"
(
change
)="
handleChangeRange
('
rain
',
$
event
)"
max=
"1"
min=
"0"
step=
"0.1"
[
disabled
]="
rainEffect =
==
undefined
"
>
<button
(
click
)="
enableParticleEffect
('
snow
')"
>
开启雪
</button>
<button
(
click
)="
snowEffect
?
disableEffect
('
snow
')
:
enableParticleEffect
('
snow
')"
>
{{ snowEffect ? '取消' : '开启' }}雪
</button>
<input
type=
"range"
(
change
)="
handleChangeRange
('
snow
',
$
event
)"
max=
"1"
min=
"0"
step=
"0.1"
[
disabled
]="
snowEffect =
==
undefined
"
>
<button
(
click
)="
enableParticleEffect
('
fog
')"
>
开启雾
</button>
<button
(
click
)="
fogEffect
?
disableEffect
('
fog
')
:
enableParticleEffect
('
fog
')"
>
{{ fogEffect ? '取消' : '开启' }}雾
</button>
<input
type=
"range"
(
change
)="
handleChangeRange
('
fog
',
$
event
)"
max=
"1"
min=
"0"
step=
"0.1"
[
disabled
]="
fogEffect =
==
undefined
"
>
<button
(
click
)="
enableParticleEffect
('
smoke
')"
>
添加烟
</button>
<button
(
click
)="
enableParticleEffect
('
fire
')"
>
添加火
</button>
...
...
src/app/components/particle-effect/particle-effect.component.ts
View file @
8a4f2259
...
...
@@ -22,6 +22,29 @@ export class ParticleEffectComponent implements OnInit {
this
.
particleEffect
=
new
smart3d
.
ParticleEffect
(
viewer
);
}
disableEffect
(
type
:
string
)
{
switch
(
type
)
{
case
'rain'
:
if
(
this
.
rainEffect
)
{
this
.
rainEffect
.
clear
();
this
.
rainEffect
=
undefined
;
}
break
;
case
'snow'
:
if
(
this
.
snowEffect
)
{
this
.
snowEffect
.
clear
();
this
.
snowEffect
=
undefined
;
}
break
;
case
'fog'
:
if
(
this
.
fogEffect
)
{
this
.
fogEffect
.
clear
();
this
.
fogEffect
=
undefined
;
}
break
;
}
}
enableParticleEffect
(
type
:
string
)
{
const
viewer
=
this
.
viewerService
.
viewer
;
const
cartesian
=
Cesium
.
Cartesian3
.
fromDegrees
(
115
,
24
,
250
);
...
...
src/app/components/pick/index.ts
0 → 100644
View file @
8a4f2259
export
*
from
'./pick.component'
;
src/app/components/pick/pick.component.css
0 → 100644
View file @
8a4f2259
src/app/components/pick/pick.component.html
0 → 100644
View file @
8a4f2259
<button
(
click
)="
handlePick
('
highlight
')"
>
高亮拾取
</button>
<button
(
click
)="
handlePick
('
offset
')"
>
偏移拾取
</button>
<button
(
click
)="
handlePick
('
transparent
')"
>
透明拾取
</button>
<button
(
click
)="
clearPick
()"
>
清除拾取效果
</button>
<button
(
click
)="
destroyPick
()"
>
取消拾取
</button>
\ No newline at end of file
src/app/components/pick/pick.component.spec.ts
0 → 100644
View file @
8a4f2259
import
{
async
,
ComponentFixture
,
TestBed
}
from
'@angular/core/testing'
;
import
{
PickComponent
}
from
'./pick.component'
;
describe
(
'PickComponent'
,
()
=>
{
let
component
:
PickComponent
;
let
fixture
:
ComponentFixture
<
PickComponent
>
;
beforeEach
(
async
(()
=>
{
TestBed
.
configureTestingModule
({
declarations
:
[
PickComponent
]
})
.
compileComponents
();
}));
beforeEach
(()
=>
{
fixture
=
TestBed
.
createComponent
(
PickComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'should create'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
src/app/components/pick/pick.component.ts
0 → 100644
View file @
8a4f2259
import
{
Component
,
OnInit
}
from
'@angular/core'
;
import
{
ViewerService
}
from
'src/app/services'
;
@
Component
({
selector
:
'app-pick'
,
templateUrl
:
'./pick.component.html'
,
styleUrls
:
[
'./pick.component.css'
]
})
export
class
PickComponent
implements
OnInit
{
private
pick
;
constructor
(
private
viewerService
:
ViewerService
,
)
{
}
ngOnInit
()
{
}
handlePick
(
type
:
'highlight'
|
'offset'
|
'transparent'
)
{
const
viewer
=
this
.
viewerService
.
viewer
;
if
(
undefined
!==
this
.
pick
)
{
this
.
pick
.
destroy
();
}
this
.
pick
=
new
smart3d
.
Pick
(
viewer
,
smart3d
.
PickMode
[
type
.
toUpperCase
()]);
this
.
pick
.
start
();
this
.
pick
.
clickEvent
.
addEventListener
((
pickedObject
,
cartesian
)
=>
{
const
degreesCartographic
=
this
.
viewerService
.
cartesianToDegreesCartographic
(
cartesian
);
alert
(
'拾取到的坐标:('
+
degreesCartographic
.
longitude
+
', '
+
degreesCartographic
.
latitude
+
', '
+
degreesCartographic
.
height
+
')'
);
});
}
clearPick
()
{
if
(
undefined
!==
this
.
pick
)
{
this
.
pick
.
clear
();
}
}
destroyPick
()
{
if
(
undefined
!==
this
.
pick
)
{
this
.
pick
.
destroy
();
}
}
}
src/app/components/tileset-clipping/tileset-clipping.component.ts
View file @
8a4f2259
import
{
Component
,
OnInit
}
from
'@angular/core'
;
import
{
ViewerService
}
from
'src/app/services'
;
const
tilesetUrl
=
'https://www.south-smart.com/cesium/modeldata/nanfangcehuiBIM/NFCH0911/CHDLFC/tileset.json'
;
@
Component
({
selector
:
'app-tileset-clipping'
,
templateUrl
:
'./tileset-clipping.component.html'
,
...
...
@@ -11,7 +9,6 @@ const tilesetUrl = 'https://www.south-smart.com/cesium/modeldata/nanfangcehuiBIM
export
class
TilesetClippingComponent
implements
OnInit
{
public
clippingPlane
:
'X'
|
'Y'
|
'Z'
=
'Z'
;
private
tileset
;
private
clipping
;
constructor
(
...
...
@@ -22,9 +19,15 @@ export class TilesetClippingComponent implements OnInit {
}
enableClipping
(
enable
?:
boolean
)
{
const
currentLayerPrimitive
=
this
.
viewerService
.
getPrimitiveByLayerName
(
this
.
viewerService
.
currentLayerName
);
if
(
!
(
currentLayerPrimitive
instanceof
Cesium
.
Cesium3DTileset
))
{
alert
(
'当前图层不是模型、倾斜或点云,不能编辑。'
);
return
;
}
const
viewer
=
this
.
viewerService
.
viewer
;
if
(
this
.
clipping
)
{
if
(
undefined
!==
this
.
clipping
)
{
this
.
clipping
.
destroy
();
}
...
...
@@ -38,26 +41,12 @@ export class TilesetClippingComponent implements OnInit {
outline
:
true
,
outlineColor
:
Cesium
.
Color
.
RED
,
edgeStylingEnabled
:
true
,
debugBoundingVolumesEnabled
:
true
,
//
debugBoundingVolumesEnabled: true,
};
const
that
=
this
;
function
createAndStartClipping
()
{
that
.
clipping
=
new
smart3d
.
Clipping
(
viewer
,
clippingOptions
);
that
.
clipping
.
start
(
that
.
tileset
,
smart3d
.
ClippingMode
[
that
.
clippingPlane
]
);
this
.
clipping
=
new
smart3d
.
Clipping
(
viewer
,
clippingOptions
);
this
.
clipping
.
start
(
currentLayerPrimitive
,
smart3d
.
ClippingMode
[
this
.
clippingPlane
]
);
viewer
.
flyTo
(
currentLayerPrimitive
);
}
if
(
undefined
===
this
.
tileset
)
{
this
.
tileset
=
viewer
.
scene
.
primitives
.
add
(
new
Cesium
.
Cesium3DTileset
({
url
:
tilesetUrl
,
}));
this
.
tileset
.
readyPromise
.
then
(
tileset
=>
{
createAndStartClipping
();
viewer
.
flyTo
(
tileset
);
});
}
else
{
createAndStartClipping
();
viewer
.
flyTo
(
this
.
tileset
);
}
}
}
src/app/components/tileset-editor/index.ts
0 → 100644
View file @
8a4f2259
export
*
from
'./tileset-editor.component'
;
src/app/components/tileset-editor/tileset-editor.component.css
0 → 100644
View file @
8a4f2259
src/app/components/tileset-editor/tileset-editor.component.html
0 → 100644
View file @
8a4f2259
<button
(
click
)="
editTileset
()"
>
开始编辑
</button>
<button
(
click
)="
saveEdit
()"
>
保存
</button>
<button
(
click
)="
resetEdit
()"
>
重置
</button>
<button
(
click
)="
cancelEdit
()"
>
取消编辑
</button>
\ No newline at end of file
src/app/components/tileset-editor/tileset-editor.component.spec.ts
0 → 100644
View file @
8a4f2259
import
{
async
,
ComponentFixture
,
TestBed
}
from
'@angular/core/testing'
;
import
{
TilesetEditorComponent
}
from
'./tileset-editor.component'
;
describe
(
'TilesetEditorComponent'
,
()
=>
{
let
component
:
TilesetEditorComponent
;
let
fixture
:
ComponentFixture
<
TilesetEditorComponent
>
;
beforeEach
(
async
(()
=>
{
TestBed
.
configureTestingModule
({
declarations
:
[
TilesetEditorComponent
]
})
.
compileComponents
();
}));
beforeEach
(()
=>
{
fixture
=
TestBed
.
createComponent
(
TilesetEditorComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'should create'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
src/app/components/tileset-editor/tileset-editor.component.ts
0 → 100644
View file @
8a4f2259
import
{
Component
,
OnInit
}
from
'@angular/core'
;
import
{
ViewerService
}
from
'src/app/services'
;
@
Component
({
selector
:
'app-tileset-editor'
,
templateUrl
:
'./tileset-editor.component.html'
,
styleUrls
:
[
'./tileset-editor.component.css'
],
})
export
class
TilesetEditorComponent
implements
OnInit
{
private
tilesetEdit
;
constructor
(
private
viewerService
:
ViewerService
,
)
{
}
ngOnInit
()
{
}
editTileset
()
{
const
currentLayerPrimitive
=
this
.
viewerService
.
getPrimitiveByLayerName
(
this
.
viewerService
.
currentLayerName
);
if
(
!
(
currentLayerPrimitive
instanceof
Cesium
.
Cesium3DTileset
))
{
alert
(
'当前图层不是模型、倾斜或点云,不能编辑。'
);
return
;
}
const
viewer
=
this
.
viewerService
.
viewer
;
if
(
undefined
!==
this
.
tilesetEdit
)
{
this
.
tilesetEdit
.
destroy
();
}
this
.
tilesetEdit
=
new
smart3d
.
TilesetEdit
({
viewer
,
model
:
currentLayerPrimitive
,
});
this
.
tilesetEdit
.
start
();
viewer
.
flyTo
(
currentLayerPrimitive
);
}
saveEdit
()
{
if
(
undefined
!==
this
.
tilesetEdit
)
{
this
.
tilesetEdit
.
save
();
// 测试缩放、旋转、平移
// this.tilesetEdit.scale(2);
// this.tilesetEdit.rotation(smart3d.EditAxisMode.Z, 45);
// this.tilesetEdit.translation(smart3d.EditAxisMode.Y, 30);
// 测试设置 3D tiles 的 modelMatrix
// this.tilesetEdit.pasteMatrix(Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(0, 0, 100)));
}
}
resetEdit
()
{
if
(
undefined
!==
this
.
tilesetEdit
)
{
this
.
tilesetEdit
.
reset
();
}
}
cancelEdit
()
{
if
(
undefined
!==
this
.
tilesetEdit
)
{
this
.
tilesetEdit
=
this
.
tilesetEdit
.
destroy
();
}
}
isUrl
(
value
:
string
):
boolean
{
// const reg = /^https?:\/\/(.)*(:)?\/?/;
const
strRegex
=
'^((https|http|ftp|rtsp|mms)?://)'
+
'?(([0-9a-z_!~*
\'
().&=+$%-]+: )?[0-9a-z_!~*
\'
().&=+$%-]+@)?'
// ftp 的 user@
+
'(([0-9]{1,3}.){3}[0-9]{1,3}'
// IP形式的URL:199.194.52.184
+
'|'
// 允许 IP 和域名
+
'([0-9a-z_!~*
\'
()-]+.)*'
// 域名的 www.
+
'([0-9a-z][0-9a-z-]{0,61})?[0-9a-z].'
// 二级域名
+
'[a-z]{2,6})'
// com
+
'(:[0-9]{1,4})?'
// 端口
+
'((/?)|'
// 如果没有文件名则不需要反斜杠
+
'(/[0-9a-z_!~*
\'
().;?:@&=+$,%#-]+)+/?)$'
;
// 文件路径
const
re
=
new
RegExp
(
strRegex
);
return
re
.
test
(
value
);
}
}
src/app/services/index.ts
View file @
8a4f2259
export
*
from
'./viewer'
;
export
*
from
'./layer-manager'
;
src/app/services/layer-manager/index.ts
deleted
100644 → 0
View file @
0bfc17a3
export
*
from
'./layer-manager.service'
;
src/app/services/layer-manager/layer-manager.service.spec.ts
deleted
100644 → 0
View file @
0bfc17a3
import
{
TestBed
}
from
'@angular/core/testing'
;
import
{
LayerManagerService
}
from
'./layer-manager.service'
;
describe
(
'LayerManagerService'
,
()
=>
{
beforeEach
(()
=>
TestBed
.
configureTestingModule
({}));
it
(
'should be created'
,
()
=>
{
const
service
:
LayerManagerService
=
TestBed
.
get
(
LayerManagerService
);
expect
(
service
).
toBeTruthy
();
});
});
src/app/services/layer-manager/layer-manager.service.ts
deleted
100644 → 0
View file @
0bfc17a3
import
{
Injectable
}
from
'@angular/core'
;
import
{
ViewerService
}
from
'../viewer'
;
@
Injectable
({
providedIn
:
'root'
})
export
class
LayerManagerService
{
private
layerManager
;
constructor
(
private
viewerService
:
ViewerService
)
{
console
.
log
(
this
.
viewerService
.
viewer
);
}
}
src/app/services/viewer/viewer.service.ts
View file @
8a4f2259
import
{
Injectable
}
from
'@angular/core'
;
import
{
Injectable
,
EventEmitter
}
from
'@angular/core'
;
@
Injectable
({
providedIn
:
'root'
...
...
@@ -8,37 +8,116 @@ export class ViewerService {
// tslint:disable-next-line: variable-name
private
_viewer
;
private
layerManager
;
private
layers
=
[];
private
measureHandler
;
public
currentLayerNameChange
:
EventEmitter
<
string
>
=
new
EventEmitter
();
public
currentLayerName
:
string
;
// 当前的图层名
constructor
()
{
console
.
log
(
'%c viewer service constructed! '
,
'background-color: red; color: white; padding: 5px'
);
this
.
handleMeasure
=
this
.
handleMeasure
.
bind
(
this
);
this
.
currentLayerNameChange
.
subscribe
(
name
=>
this
.
currentLayerName
=
name
);
}
get
viewer
()
{
return
this
.
_viewer
;
}
/**
* 初始化 Viewer 和图层管理类
* @param container HTML 标签或标签 ID
* @param options 见 smart3d.Viewer
*/
initViewer
(
container
:
string
|
Element
,
options
?:
object
):
object
{
if
(
!
this
.
_viewer
)
{
this
.
_viewer
=
new
smart3d
.
Viewer
(
container
,
options
||
{});
this
.
layerManager
=
new
smart3d
.
LayerManager
(
this
.
_viewer
);
// tslint:disable-next-line
: no-string-literal
window
[
'viewer'
]
=
this
.
_viewer
;
// tslint:disable-next-line
window
[
'viewer'
]
=
this
.
_viewer
;
window
[
'layerManager'
]
=
this
.
layerManager
;
window
[
'primitives'
]
=
this
.
viewer
.
scene
.
primitives
.
_primitives
;
window
[
'layers'
]
=
this
.
layers
;
}
return
this
.
_viewer
;
}
/**
* 添加图层
* @param layer smart3d.Layer
*/
addLayer
(
layer
)
{
this
.
layerManager
.
addLayer
(
layer
);
if
(
!
(
layer
instanceof
smart3d
.
Layer
))
{
layer
=
new
smart3d
.
Layer
(
layer
);
}
this
.
layers
.
push
(
layer
);
this
.
layerManager
.
add
(
layer
);
}
removeLayerByName
(
name
:
string
):
void
{
const
layer
=
this
.
getLayerByName
(
name
);
const
layerIndex
=
this
.
getLayerIndexByName
(
name
);
if
(
undefined
!==
layer
)
{
this
.
layerManager
.
remove
(
layer
);
this
.
layers
.
splice
(
layerIndex
,
1
);
}
}
toggleLayerShow
(
name
:
string
)
{
const
layer
=
this
.
getLayerByName
(
name
);
if
(
undefined
!==
layer
)
{
layer
.
show
=
!
layer
.
show
;
this
.
layerManager
.
setVisible
(
layer
);
}
}
/**
* 根据图层名获取图层
* @param name 图层名
* @returns smart3d.Layer | undefined
*/
private
getLayerByName
(
name
:
string
)
{
return
this
.
layers
.
find
(
layer
=>
layer
.
name
===
name
);
}
flyToLayer
(
layer
)
{
private
getLayerIndexByName
(
name
:
string
):
number
{
return
this
.
layers
.
findIndex
(
layer
=>
layer
.
name
===
name
);
}
/**
* 获取图层底下的原始数据
* @param name 图层名
* @returns Cesium3DTileset | DataSource | ImageryLayer | undefined
*/
getPrimitiveByLayerName
(
name
:
string
)
{
const
layer
=
this
.
getLayerByName
(
name
);
return
layer
?
this
.
layerManager
.
getLayer
(
layer
)
:
undefined
;
}
/**
* 将相机视角设为该图层
* @param layer smart3d.Layer
*/
flyToLayer
(
layer
):
void
{
this
.
layerManager
.
flyTo
(
layer
);
}
handleMeasure
(
measureMode
:
number
,
isGround
?:
boolean
,
showLabel
?:
boolean
)
{
/**
* 将相机视角设为图层名对应的图层
* @param name 图层名
*/
flyToLayerByName
(
name
:
string
):
void
{
const
currentLayer
=
this
.
getLayerByName
(
name
);
if
(
undefined
!==
currentLayer
)
{
this
.
flyToLayer
(
currentLayer
);
}
}
/**
* 开启测量
* @param measureMode 测量模型,例如距离测量、面积测量
* @param isGround 是否是贴地测量
* @param showLabel 是否显示测量结果
*/
handleMeasure
(
measureMode
:
number
,
isGround
?:
boolean
,
showLabel
?:
boolean
):
void
{
if
(
measureMode
!==
smart3d
.
MeasureMode
.
Distance
&&
measureMode
!==
smart3d
.
MeasureMode
.
Angle
&&
...
...
@@ -56,4 +135,24 @@ export class ViewerService {
this
.
measureHandler
.
activate
();
}
}
/**
* 笛卡尔坐标转角度制的经纬度高度
* @param cartesian 笛卡尔坐标
*/
cartesianToDegreesCartographic
(
cartesian
:
{
x
:
number
;
y
:
number
;
z
:
number
}):
{
longitude
:
number
,
latitude
:
number
;
height
:
number
}
{
const
cartographic
=
Cesium
.
Cartographic
.
fromCartesian
(
cartesian
);
const
longitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
longitude
);
const
latitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
latitude
);
const
height
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
height
);
return
{
longitude
,
latitude
,
height
};
}
}
src/styles.css
View file @
8a4f2259
/* You can add global styles to this file, and also import other style files */
body
{
margin
:
0
;
padding
:
0
;
}
.text-white
{
...
...
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