Commit 9a9e9c3f authored by 吴虎啸's avatar 吴虎啸

测试

parent 2bbdefbb
Pipeline #19387 passed with stage
clone:
git:
image: registry-vpc.cn-qingdao.aliyuncs.com/wod-devops/git:1.4.0
pipeline:
read-cache:
image: registry-vpc.cn-qingdao.aliyuncs.com/wod-devops/cache:latest
restore: true
mount:
- ./node_modules
volumes:
- /cache:/cache
build:
image: registry-vpc.cn-qingdao.aliyuncs.com/wod-devops/node:8.15.0-onbuild
volumes:
- /cache/yarn:/usr/local/share/.cache/yarn
commands:
- yarn install
- yarn run build
store-cache:
image: registry-vpc.cn-qingdao.aliyuncs.com/wod-devops/cache:latest
rebuild: true
mount:
- ./node_modules
volumes:
- /cache:/cache
docker-master:
image: registry-vpc.cn-qingdao.aliyuncs.com/wod-devops/docker:1.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
base: registry-vpc.cn-qingdao.aliyuncs.com/wod/nginx:1.15.9-alpine
repo: whx/note
tag: 1.0.0
registry: hub.wodcloud.com
when:
branch: master
deploy:
image: registry-vpc.cn-qingdao.aliyuncs.com/wod-devops/kubernetes:1.0
namespace: bg-test
deployment: whx-note
container: whx-note
registry: hub.wodcloud.com
secrets:
- source: REGISTRY_USER_ALIYUN
target: REGISTRY_USER
- source: REGISTRY_PASSWORD_ALIYUN
target: REGISTRY_PASSWORD
when:
branch: [master]
branches: [master,dev]
node_modules/
\ No newline at end of file
name: Node CI
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
# node-version: [8.x, 10.x, 12.x]
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Build and Deploy
uses: JamesIves/github-pages-deploy-action@master
env:
ACCESS_TOKEN: ${{ secrets.HUAWEI_CLOUD }}
# BASE_BRANCH: master # The branch the action should deploy from.
BRANCH: deploy-pages # The branch the action should deploy to.
FOLDER: note
BUILD_SCRIPT: npm install && npm install -g gitbook-cli && gitbook build .
.DS_Store
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
_book
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
dist
\ No newline at end of file
# 简介页
## [ArcGIS API for JavaScript4.x](arcgis-api-for-javascript4.x/README.md)
## [ArcGIS API for JavaScript3.x](arcgis-api-for-javascript3.x.md)
## [VUE](vue.md)
## [Docker](docker/)
## [小技巧](untitled.md)
## [CI/CD](ci-cd.md)
# Table of contents
* [简介页](README.md)
* [ArcGIS API for JavaScript4.x](arcgis-api-for-javascript4.x/README.md)
* [学习技巧](arcgis-api-for-javascript4.x/xue-xi-he-kai-fa-ji-qiao.md)
* [开发技巧](arcgis-api-for-javascript4.x/kai-fa-ji-qiao.md)
* [MapImageLayer](arcgis-api-for-javascript4.x/mapimagelayer.md)
* [FeatureLayer](arcgis-api-for-javascript4.x/featurelayer.md)
* [GraphicLayer](arcgis-api-for-javascript4.x/graphiclayer.md)
* [Renderer](arcgis-api-for-javascript4.x/renderer.md)
* [2DSymbol](arcgis-api-for-javascript4.x/symbol.md)
* [地图事件之地图状态监听](arcgis-api-for-javascript4.x/di-tu-shi-jian.md)
* [地图事件之点击](arcgis-api-for-javascript4.x/di-tu-shi-jian-zhi-dian-ji.md)
* [模拟点运动图层](arcgis-api-for-javascript4.x/mo-ni-dian-yun-dong-tu-ceng.md)
* [集成echarts实现迁徙图特效](arcgis-api-for-javascript4.x/untitled.md)
* [实现点聚合效果](arcgis-api-for-javascript4.x/shi-xian-dian-ju-he-xiao-guo.md)
* [ArcGIS API for JavaScript3.x](arcgis-api-for-javascript3.x.md)
* [VUE](vue.md)
* [Docker](docker/README.md)
* [Docker使用Nginx代理转发SSR](docker/docker-shi-yong-nginx-dai-li-zhuan-fa-ssr.md)
* [Docker搭建个人wordpress网站](docker/docker-da-jian-ge-ren-wordpress-wang-zhan.md)
* [Docker安装](docker/docker-an-zhuang.md)
* [Nginx](nginx.md)
* [小技巧](untitled.md)
* [CI/CD](ci-cd.md)
* [test](test.md)
# ArcGIS API for JavaScript3.x
# ArcGIS API for JavaScript4.x
## [学习技巧](xue-xi-he-kai-fa-ji-qiao.md)
## [开发技巧](kai-fa-ji-qiao.md)
## [MapImageLayer](mapimagelayer.md)
## [FeatureLayer](featurelayer.md)
## [GraphicLayer](graphiclayer.md)
## [Renderer](renderer.md)
## [2DSymbol](symbol.md)
## [地图事件之地图状态监听](di-tu-shi-jian.md)
## [地图事件之点击](di-tu-shi-jian-zhi-dian-ji.md)
## [模拟点运动图层](mo-ni-dian-yun-dong-tu-ceng.md)
## [集成echarts实现迁徙图特效](untitled.md)
## [实现点聚合效果](shi-xian-dian-ju-he-xiao-guo.md)
## [实现轨迹运动效果](guiji.md)
\ No newline at end of file
# 地图事件之点击
```javascript
view.on("click", function(event) {
//可以直接调用event的地图坐标进行空间查询
//也可以使用封装的方法进行点击查询
view.hitTest(screenpoint).then(function(response) {
//screenpoint是屏幕坐标
//查询对象是featurelayer和graphiclayer,mapserver里面的图层不参与查询,
//若想让其中的图层参与查询,参考mapimagelayer中的用法
})
})
```
# 地图事件之地图状态监听
## watch
```javascript
mainView.watch("extent", updateOverviewExtent);
```
watch方法是accessor类的方法,只要是继承它的都可以监听具体的属性。Arcgis api 的所有类都继承accessor类,因此此方法最通用
## watchUtils.when
```javascript
watchUtils.when(mainView, "stationary", updateOverview);
```
watchUtils.when方法也是监听,但是只有监听的属性为true 时,才执行给定的方法
## view.whenLayerView
监听图层加载完成,当图层加载完成后,调用之后的方法
```javascript
view.whenLayerView(featureLayer).then(function(layerView) {
layerView.watch("updating", function(value) {
}
}
```
# GraphicLayer
## 应用场景
解析json数据时,或者临时在地图上添加要素时使用
```text
graphic = new Graphic(pt, symbol, attr, popupTemplate);
graphiclayer.add(graphic);
```
GraphicLayer是FeatureLayer的子类
# 开发技巧
代码开发时,将map,view等对象声明为全局变量
在调试时,在console控制台输入map等即可访问当前页面中地图的属性。
![](../.gitbook/assets/image%20%2812%29.png)
# MapImageLayer
## 使用场景
调用Arcgis Server上面的地图服务时
当地图服务中有多个图层时,使用sublayers进行图层管理
```text
var layer = new MapImageLayer({
url:
"https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer",
title: "Census Demographics",//图层标签,方便筛选
sublayers: [
{
id: 0,//对应server上的图层编号,必要属性
title: "Population/square mile",
renderer: populationRenderer,//自定义图层渲染,覆盖server上面初始的渲染
visible: false,//可以控制图层显示与否
//自定义标签
labelingInfo: [
{
labelExpression: "[POP2007]",
labelPlacement: "always-horizontal",
symbol: {
type: "text", // autocasts as new TextSymbol()
color: "white",
haloColor: "#3d6a89",
haloSize: 1,
font: {
size: 10
}
},
minScale: 37000
}
],
//图层内要素的弹出模板
popupTemplate: {
// autocasts as new PopupTemplate()
title: "{states.STATE_NAME}",
content: [
{
type: "fields",
fieldInfos: [
{
fieldName: "states.POP2007",
label: "Total population",
visible: true,
format: {
digitSeparator: true,
places: 0
}
},
}
]
}
]
},
opacity: 0.6,//图层透明度0~1,0表示不透明
source: {
mapLayerId: 1//数据源 对应server上的图层编号,必要属性
}
}
]
});
```
筛选出图层
```text
var norwegianSublayer = layer.sublayers.find(function(sublayer) {
return (
sublayer.title === "Share of population with Norwegian Ancestry"
);
});
```
对指定图层进行查询
```text
var querylayer = mapserverlayer.findSublayerById(
parseInt(index)//需要查询操作的图层id
);
var query = querylayer.createQuery();
query.geometry = point;//空间查询
query.outFields = ["*"];
query.distance = 2;
query.units = "miles";
query.returnGeometry = true;
querylayer.queryFeatures(query).then(function(result) {
if (result.features.length > 0) {
view.popup.open({
location: point,
features: result.features
});
return;
}
});
```
# 模拟点运动图层
## 原理
通过对graphiclayer的不断刷新,加载变换的数据源,注意深、浅拷贝,使用clone\(\)方法
```text
graphics = graphiclayer.graphics.clone();
//获取数据源,使用深拷贝,不改变原数据源
timer = setInterval(() => {
//临时运动图层初始化,清空
movelayer.removeAll();
linemovelayer.removeAll();
for (var i = 0; i < selectedGraphics.length; i++) {
//根据数据源的属性信息如,车辆的方向
var angle =
((2 * Math.PI) / 360) * graphics[i].attributes.direction;
//循环运动,运动50次后,回到起点
if (movecounts == 50) {
graphics[i].geometry.x -= 0.025 * Math.sin(angle);
graphics[i].geometry.y -= 0.025 * Math.cos(angle);
graphics[i].geometry.paths[0] = graphics[i].geometry.paths[0].slice(0, 1)
} else {
graphics[i].geometry.x += 0.0005 * Math.sin(angle);
graphics[i].geometry.y += 0.0005 * Math.cos(angle);
graphics[i].geometry.paths[0].push([selectedGraphics[i].geometry.x, selectedGraphics[i].geometry.y
])
}
var graphic = selectedGraphics[i].clone();
graphic.symbol.angle = graphic.attributes.direction - 90;
movelayer.add(graphic);
var lineGraphic = selectedLineGraphic[i].clone();
linemovelayer.add(lineGraphic);
if (movecounts == 50) {
movecounts = 0;
}
},150)
```
# Renderer
| 需求 | 实现需求的渲染 |
| :--- | :--- |
| 只根据位置信息渲染 | SimpleRenderer, HeatmapRenderer |
| 根据属性唯一值渲染 | UniqueValueRenderer |
| 分段值渲染 | ClassBreakRenderer |
| 连续值,多字段渲染 | SimpleRenderer,UniqueValueRenderer,visualVariables |
## SimpleRenderer
```text
renderer = {
type: "simple", // autocasts as new SimpleRenderer()
symbol: { type: "simple-fill" }, // autocasts as new SimpleFillSymbol()
visualVariables: [{
type: "color",
field: "POPULATION",
normalizationField: "SQ_KM",
// features with 30 ppl/sq km or below are assigned the first color
stops: [{ value: 100, color: "#FFFCD4" },
{ value: 500, color: "#0D2644" }]
}]
};
```
## HeatmapRenderer
```text
renderer = {
type: "heatmap",
field: "crime_count",
colorStops: [
{ ratio: 0, color: "rgba(255, 255, 255, 0)" },
{ ratio: 0.2, color: "rgba(255, 255, 255, 1)" },
{ ratio: 0.5, color: "rgba(255, 140, 0, 1)" },
{ ratio: 0.8, color: "rgba(255, 140, 0, 1)" },
{ ratio: 1, color: "rgba(255, 0, 0, 1)" }
],
minPixelIntensity: 0,
maxPixelIntensity: 5000
};
```
## UniqueValueRenderer
```text
renderer = {
type: "unique-value", // autocasts as new UniqueValueRenderer()
field: "REGION",
field2: "RANK",
field3: "CLASS",
fieldDelimiter: ", ", // comma + space used to separate values from all fields
uniqueValueInfos: [
{
value: "North, 1, medium", // features in the "North" region, a rank of 1, and "medium" class
symbol: sym1 // will be assigned sym1
}, {
value: "North, 2, medium", // features in the "North" region, a rank of 2, and a "medium class
symbol: sym2 // will be assigned sym2
},
...
],
visualVariables: [{
type: "opacity",
field: "POPULATION",
normalizationField: "SQ_KM",
// features with 30 ppl/sq km or below are assigned the first opacity value
stops: [{ value: 100, opacity: 0.15 },
{ value: 1000, opacity: 0.90 }]
}]
};
renderer.addUniqueValueInfo({
});
```
## ClassBreakRenderer
```text
renderer = {
type: "class-breaks", // autocasts as new ClassBreaksRenderer()
field: "HARVESTED_ACRES",
classBreakInfos: [
{
minValue: 0, // 0 acres
maxValue: 200000, // 200,000 acres
symbol: sym1, // will be assigned sym1
label: "fewer than 200,000 acres"
}, {
minValue: 200001, // 200,001 acres
maxValue: 500000, // 500,000 acres
symbol: sym2, // will be assigned sym2
label: "200,000 - 500,000 acres"
}, {
minValue: 500001, // 500,001 acres
maxValue: 750000, // 750,000 acres
symbol: sym3, // will be assigned sym2
label: "more than 500,000 acres"
}
]
};
renderer.addClassBreakInfo({
});
```
##
# 实现点聚合效果
需要二次开发的js库的导入,js文件如文末
# 2DSymbol
| 类型 | 渲染 |
| :--- | :--- |
| 点 | [SimpleMarkerSymbol](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-SimpleMarkerSymbol.html), [PictureMarkerSymbol](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-PictureMarkerSymbol.html), [TextSymbol](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-TextSymbol.html) |
| 线 | [SimpleLineSymbol](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-SimpleLineSymbol.html), [TextSymbol](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-TextSymbol.html) |
| 面 | [SimpleFillSymbol](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-SimpleFillSymbol.html), [PictureFillSymbol](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-PictureFillSymbol.html), [SimpleMarkerSymbol](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-SimpleMarkerSymbol.html), [TextSymbol](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-TextSymbol.html) |
## SimpleMarkerSymbol
```javascript
var symbol = {
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
style: "square",//circle,cross,diamond,square,triangle,x
color: "blue",
size: "8px", // pixels
outline: { // autocasts as new SimpleLineSymbol()
color: [ 255, 255, 0 ],
width: 3 // points
},
xoffset: 2px,
yoffset: 2px
};
```
## PictureMarkerSymbol
```javascript
var symbol = {
type: "picture-marker", // autocasts as new PictureMarkerSymbol()
url: "https://static.arcgis.com/images/Symbols/Shapes/BlackStarLargeB.png",
width: "64px",
height: "64px",
angle: 45,
xoffset: 2px,
yoffset: 2px
};
```
## TextSymbol
```javascript
var textSymbol = {
type: "text", // autocasts as new TextSymbol()
color: "white",
//光晕
haloColor: "black",
haloSize: "1px",
text: "You are here",
xoffset: 3,
yoffset: 3,
font: { // autocasts as new Font()
size: 12,
family: "Josefin Slab",
weight: "bold"
},
angle: 45,
backgroundColor: "black",
borderLineColor: "black",
borderLineSize: 2,
horizontalAlignment :"",//left | right | center | justify
kerning : true,//是否适应字距
rotated : false//是否旋转
verticalAlignment :"",// baseline | top | middle | bottom
};
```
## SimpleLineSymbol
## SimpleFillSymbol
## PictureFillSymbol
# 集成echarts实现迁徙图特效
Arcgis api for js中使用echart是,需要使用坐标映射js,文件在文末:可根据需求修改
在Arcgis中注入js,
```text
esriLoader
.loadModules([
"./static/assets/echarts/4EchartsLayer.js",
"dojo/domReady!"
])
.then(([echartsLayer]) => {
echartlayer = new echartsLayer(view, echarts, option);
})
.catch(err => {
// handle any errors
console.error(err);
});
```
注意在option.series\[index\].coordinateSystem设置坐标系为"arcgis",之后可以去echarts官网下载模板,组装数据即可实现
```text
define(["dojo/_base/declare", "dojo/_base/lang", "esri/geometry/Point", "esri/geometry/SpatialReference"],
function (declare, lang, n, SpatialReference) {
return declare("EchartsLayer", null, {
name: "EchartsLayer",
view: null,
box: null,
chart: null,
chartOption: null,
visible: true,
echartsLib: null,
constructor: function (view, echarts, option) {
this.echartsLib = echarts;
if (option.series) {
option.series.forEach(element => {
if (element.type === 'heatmap' && element.coordinateSystem === 'arcgis_geo') {
this.echartsLib.registerCoordinateSystem('arcgis_geo', this.getGeoCoordinateSystem(view, echarts));
} else {
this.echartsLib.registerCoordinateSystem('arcgis', this.getE3CoordinateSystem(view, echarts));
}
})
}
if (option.baseOption) {
option.baseOption.series.forEach(element => {
if (element.type === 'heatmap' && element.coordinateSystem === 'arcgis_geo') {
this.echartsLib.registerCoordinateSystem('arcgis_geo', this.getGeoCoordinateSystem(view, echarts));
} else {
this.echartsLib.registerCoordinateSystem('arcgis', this.getE3CoordinateSystem(view, echarts));
}
})
}
this.init(view, option);
},
init: function (view, option) {
this.setBaseMap(view);
this.createLayer();
option && this.setChartOption(option);
},
setBaseMap: function (view) {
this.view = view;
},
setChartOption: function (option) {
this.chartOption = option;
this.setCharts();
},
setVisible: function (bool) {
if (!this.box || this.visible === bool) return;
this.box.hidden = !bool;
this.visible = bool;
bool === true && setCharts();
},
refreshBegin: function () {
this.box.hidden = true;
},
refreshing: function () {
setCharts();
},
refreshEnd: function () {
this.box.hidden = false;
},
on: function (eventName, handler, context) {
this.chart.on(eventName, handler, context);
},
off: function (eventName, handler, context) {
this.chart.off(eventName, handler, context);
},
map_DragStart_Listener: null,
map_DragEnd_Listener: null,
map_ZoomStart_Listener: null,
map_ZoomEnd_Listener: null,
map_ExtentChange_Listener: null,
map_click_Listener: null,
setCharts: function () {
if (!this.visible) return;
if (this.chartOption == null || this.chartOption == 'undefined') return;
let baseExtent = this.view.extent;
//判断是否使用了mark类型标签,每次重绘要重新转换地理坐标到屏幕坐标
//根据地图extent,重绘echarts
this.chartOption.xAxis = { show: false, splitLine: {show: false}, min: baseExtent.xmin, max: baseExtent.xmax };
this.chartOption.yAxis = { show: false, splitLine: {show: false}, min: baseExtent.ymin, max: baseExtent.ymax };
this.chart.setOption(this.chartOption);
this.chartOption.animation = false;
},
/*创建layer的容器,添加到map的layers下面*/
createLayer: function () {
let box = this.box = document.createElement("div");
box.id = "echarts-div"
box.style.width = this.view.width + 'px';
box.style.height = this.view.height + 'px';
box.style.position = "absolute";
box.style.top = 0;
box.style.left = 0;
const parent = this.view.container.getElementsByClassName("esri-view-surface")[0];
parent.appendChild(box);
this.chart = this.echartsLib.init(box);
this.startMapEventListeners();
},
/*销毁实例*/
removeLayer: function () {
this.box.outerHTML = "";
this.view = null;
this.box = null;
this.originLyr = null;
this.features = null;
this.screenData = [];
this.chart = null;
this.chartOption = null;
this.map_DragStart_Listener.remove();
this.map_DragEnd_Listener.remove();
this.map_ZoomStart_Listener.remove();
this.map_ZoomEnd_Listener.remove();
this.map_ExtentChange_Listener.remove();
},
/*监听地图事件,根据图层是否显示,判断是否重绘echarts*/
startMapEventListeners: function () {
let view = this.view;
view.watch("extent", lang.hitch(this, function () {
if (!this.visible) return;
this.setCharts();
this.chart.resize();
this.box.hidden = false;
}));
view.watch("rotation", lang.hitch(this, function () {
if (!this.visible) return;
this.setCharts();
this.chart.resize();
this.box.hidden = false;
}));
function cloneEvent(e) {
if (e===undefined || e===null) return undefined;
function ClonedEvent() {};
let clone=new MouseEvent('click');
for (let p in e) {
let d=Object.getOwnPropertyDescriptor(e, p);
if (d && (d.get || d.set)) Object.defineProperty(clone, p, d); else clone[p] = e[p];
}
Object.setPrototypeOf(clone, e);
return clone;
}
view.on('click', lang.hitch(this, function (e) {
const old = e.native
let evt = new MouseEvent('click', {
altKey: old.altKey,
button: old.button,
buttons: old.buttons,
clientX: old.clientX,
clientY: old.clientY,
ctrlKey: old.ctrlKey,
metaKey: old.metaKey,
movementX: old.movementX,
movementY: old.movementY,
offsetX: old.offsetX,
offsetY: old.offsetY,
pageX: old.pageX,
pageY: old.pageY,
region: old.region,
screenX: old.screenX,
screenY: old.screenY,
shiftKey: old.shiftKey,
which: old.which,
x: old.x,
y: old.y,
})
this.chart.getDom().getElementsByTagName('div')[0].dispatchEvent(evt)
}))
},
getE3CoordinateSystem: function (map, echarts) {
var CoordSystem = function CoordSystem(map) {
this.map = map;
this._mapOffset = [0, 0];
};
CoordSystem.create = function (ecModel) {
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.get('coordinateSystem') === 'arcgis') {
seriesModel.coordinateSystem = new CoordSystem(map);
}
});
};
CoordSystem.getDimensionsInfo = function () {
return ['x', 'y'];
};
CoordSystem.dimensions = ['x', 'y'];
CoordSystem.prototype.dimensions = ['x', 'y'];
CoordSystem.prototype.setMapOffset = function setMapOffset(mapOffset) {
this._mapOffset = mapOffset;
}
CoordSystem.prototype.dataToPoint = function dataToPoint(data) {
var point = {
type: "point",
x: data[0],
y: data[1],
spatialReference: new SpatialReference(4326)
};
var px = map.toScreen(point);
var mapOffset = this._mapOffset;
return [px.x - mapOffset[0], px.y - mapOffset[1]];
}
CoordSystem.prototype.pointToData = function pointToData(pt) {
var mapOffset = this._mapOffset;
var screentPoint = {
x: pt[0] + mapOffset[0],
y: pt[1] + mapOffset[1]
};
var data = map.toMap(screentPoint);
return [data.x, data.y];
};
CoordSystem.prototype.getViewRect = function getViewRect() {
return new echarts.graphic.BoundingRect(0, 0, this.map.width, this.map.height);
};
CoordSystem.prototype.getRoamTransform = function getRoamTransform() {
return echarts.matrix.create();
};
return CoordSystem
},
getGeoCoordinateSystem: function (map, echarts) {
var CoordSystem = function CoordSystem(map) {
this.map = map;
this._mapOffset = [0, 0];
};
CoordSystem.create = function (ecModel) {
ecModel.eachSeries(function (seriesModel) {
if (seriesModel.get('coordinateSystem') === 'arcgis_geo') {
seriesModel.coordinateSystem = new CoordSystem(map);
}
});
};
CoordSystem.getDimensionsInfo = function () {
return ['lng', 'lat'];
};
CoordSystem.dimensions = ['lng', 'lat'];
CoordSystem.prototype.dimensions = ['lng', 'lat'];
CoordSystem.prototype.setMapOffset = function setMapOffset(mapOffset) {
this._mapOffset = mapOffset;
}
CoordSystem.prototype.dataToPoint = function dataToPoint(data) {
var point = {
type: "point",
x: data[0],
y: data[1],
spatialReference: new SpatialReference(4326)
};
var px = map.toScreen(point);
var mapOffset = this._mapOffset;
return [px.x - mapOffset[0], px.y - mapOffset[1]];
}
CoordSystem.prototype.pointToData = function pointToData(pt) {
var mapOffset = this._mapOffset;
var screentPoint = {
x: pt[0] + mapOffset[0],
y: pt[1] + mapOffset[1]
};
var data = map.toMap(screentPoint);
return [data.x, data.y];
};
CoordSystem.prototype.getViewRect = function getViewRect() {
return new echarts.graphic.BoundingRect(0, 0, this.map.width, this.map.height);
};
CoordSystem.prototype.getRoamTransform = function getRoamTransform() {
return echarts.matrix.create();
};
return CoordSystem
}
});
})
```
# 学习技巧
官网下载所有4.x版本的示例代码
"[https://developers.arcgis.com/javascript/latest/sample-code/source-code.zip](https://developers.arcgis.com/javascript/latest/sample-code/source-code.zip)"
解压后在VScode中打开使用搜索功能,快速找到引用
![](../.gitbook/assets/image%20%281%29.png)
博客推荐
"[https://www.cnblogs.com/onsummer/tag/ArcGIS API for Javascript/default.html?page=3](https://www.cnblogs.com/onsummer/tag/ArcGIS%20API%20for%20Javascript/default.html?page=3)"
FROM {{ BASEIMAGE }}
MAINTAINER {{ AUTHOR }}
LABEL Author={{ AUTHOR }} Name={{ PROJECT }} Version={{ VERSION }}
ADD ./_book /usr/share/nginx/html
# CI/CD
## 简述
gitbook是依赖于nodejs的工具包,可以将markdown文档处理为html网页进行发布。gitbook处理后的文档,笔记效果很好,条理清楚,页面美观。但是markdown文档撰写不方便,没有交互式的体验。后来去了gitbook的官网,在这上面快速方便的撰写,效率很高,并且可以同步到github上面去。但是由于gitbook需要科学上网才能访问,写的文档需要同步部署到国内需要CI/CD的支持。
## 一、gitbook注册与使用并绑定github账号(科学上网)
官网[https://app.gitbook.com](https://app.gitbook.com),注册后绑定github账号即可
![](.gitbook/assets/wei-xin-jie-tu-20190929173440.png)
## 二、github配置
![](.gitbook/assets/image%20%2810%29.png)
webhook是github对外通信的插件,此项目绑定两个webhook,一个是gitbook的官网,一个是你所需要通知更改的服务器。上面的那个在第一步后会自动生成,下面的需要自己去加,并且需要secret类似密钥。只有携带secret的访问才会触发服务器上面的进程。
![](.gitbook/assets/image%20%287%29.png)
## 三、服务器配置
参考资料[https://segmentfault.com/a/1190000016071010](https://segmentfault.com/a/1190000016071010)
当github上面的代码触发push动作后,调用webhook向外发通知。因此,服务器要实时的监听github给它的信息,需要使用github-webhook-handler进行实时的监听。同时也需要pm2进行守护进程。这两个工具都需要nodejs的支持,因此需要提前安装node环境。
安装webhook的监听
```
npm i -g github-webhook-handler
```
新建一个webhook.js的文件
```text
var http = require('http')
var createHandler = require('github-webhook-handler')
var handler = createHandler({ path: '/', secret: '****' })
// 上面的 secret 保持和 GitHub 后台设置的一致
function run_cmd(cmd, args, callback) {
var spawn = require('child_process').spawn;
var child = spawn(cmd, args);
var resp = "";
child.stdout.on('data', function(buffer) { resp += buffer.toString(); });
child.stdout.on('end', function() { callback (resp) });
}
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(7777)
handler.on('error', function (err) {
console.error('Error:', err.message)
})
handler.on('push', function (event) {
console.log('Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref);
run_cmd('sh', ['./deploy.sh',event.payload.repository.name], function(text){ console.log(text) });
})
```
上面的文件是监听的处理文件,是一个静态的js脚本文件,是对github的webhook的处理,如果响应成功,会执行同一个目录下的shell脚本deploy.sh。因此需要在同一个目录下新建一个deploy.sh文件
```text
#!/bin/bash
# 网站的根目录
WEB_PATH='/home/wwwroot/domain.com'
echo "start deployment"
cd $WEB_PATH
echo "fetching from remote..."
# 为了避免冲突,强制更新本地文件
git fetch --all
git reset --hard origin/master
echo "done"
```
上述的WEB\_PATH是git项目的路径,
注意:shell脚本的格式问题,先执行sed -i 's/\r$//' deploy.sh进行格式化。
注意:要初始化拉取一下代码,绑定git。
使用pm2守护进程
安装pm2:
```text
npm i pm2 -g
```
运行webhook.js
```text
pm2 start webhook.js
```
## 四、网页发布
前段时间,github支持CI/CD,可以通过在.github/workflow文件目录,下编写yaml文件,执行cicd。如下
```text
name: Node CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
# node-version: [8.x, 10.x, 12.x]
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: npm install, build, and test
run: |
npm install
npm install -g gitbook-cli
gitbook init
gitbook build .
env:
CI: true
```
上述文件可以将markdown文档自动构建为网页,但是将gitbook build的结果进行持续发布时,未能找到相关的文档。卒。。。
因此,只能在本地安装gitbook,通过gitbook build命令,在文件目录下生成html文件,上传到项目内。
![](.gitbook/assets/image%20%283%29.png)
最后,在服务器,使用docker启动一个nginx,将WEB\_PATH里面的项目下的\_book目录挂载到nginx中,一条命令解决。
```text
docker run -p 4000:80 --name gitbook -d nginx -v /whx/note/_book:/usr/share/nginx/html
```
## 五、流程图与总结
![](.gitbook/assets/wei-ming-ming-wen-jian.png)
不需要关注markdown文件的语法与html的情况,使用gitbook官网的方式写文档,最后托管在github上面,使用git分布式的理念,便于网站的迁移。
可惜的是未用到github上面的CI/CD,在本地进行手动的集成。
# Docker
## [Docker 安装](docker-an-zhuang.md)
"../.gitbook/assets/docker\_practice.epub"
## [Docker 之搭建个人wordpress网站](docker-da-jian-ge-ren-wordpress-wang-zhan.md)
## [Docker之使用Nginx代理转发SSR](docker-shi-yong-nginx-dai-li-zhuan-fa-ssr.md)
# Docker安装
### Windows 10安装docker
Windows 10 pro(专业版)可直接去docker官网安装 [Docker for Windows Installer.exe](https://download.docker.com/win/stable/Docker%20for%20Windows%20Installer.exe)
Windows 10 家庭版安装
1. 升级为专业版
搜索专业版激活码,在电脑设置-关于电脑中升级
![](../.gitbook/assets/image%20%288%29.png)
2. 安装[Docker for Windows Installer.exe](https://download.docker.com/win/stable/Docker%20for%20Windows%20Installer.exe)
3. 配置启动Hyper-V服务
在电脑的服务配置中,启用服务
![](../.gitbook/assets/image%20%2811%29.png)
4. 使用cmd命令启动虚拟机服务
pushd “%~dp0” dir /b %SystemRoot%\servicing\Packages_Hyper-V_.mum &gt;hyper-v.txt for /f %%i in \(‘findstr /i . hyper-v.txt 2^&gt;nul’\) do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages%%i" del hyper-v.txt Dism /online /enable-feature /featurename:Microsoft-Hyper-V-All /LimitAccess /ALL
保存以上内容到txt文件,改文件名扩展为.cmd文件,以管理员身份运行此cmd文件即可
# Docker搭建个人wordpress网站
## Getting Super Powers
拉取镜像mariadb和wordpress镜像
```
docker pull wordpress
docker pull mariadb
```
启动数据库服务
```text
docker run --name wp-db -e MYSQL_ROOT_PASSWORD=123456 -d mariadb
```
说明:--name后面是容器的名称,MYSQL\_ROOT\_PASSWORD=123456为数据库用户root的密码为123456,-d表示此数据库容器后台运行,mariadb表示镜像
启动wordpress服务
```text
docker run --name mywordpress --link wp-db:mysql -p 8001:80 -d wordpress
```
说明:--link为数据库关联,注意此处wp-db后为mysql不是mariadb ,-p表示端口映射
打开IP:8081网址,语言选择香港,即可进入注册安装。
# Docker使用Nginx代理转发SSR
SSR由于使用的是国外的VPS的ip,会有很大几率被国内网络屏蔽,例如本人自搭的SSR在家里使用电信网络没问题,到公司后使用移动网络被屏蔽。
解决方法之一就是使用华为云等国内服务器进行代理转发,本文介绍的是使用docker进行Nginx代理转发。
nginx配置文件
```
user root;
worker_processes 1;
events {
worker_connections 1024;
}
stream {
upstream group1 {
hash $remote_addr consistent;
server 108.61.XXX.XXX:2333; # ip:port
}
server {
listen 2333;
listen 2333 udp;
proxy_pass group1;
}
}
```
docker-compose.yml文件
```
version: '2'
services:
nginx_lb:
image: nginx:latest
ports:
- "2333:2333"
- "2333:2333/udp"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
```
使用docker-compose启动nginx
```text
docker-compose up -d
```
启动配置SSR连接,用国内服务器的公网ip替换vps的ip,如图
![](../.gitbook/assets/image%20%2813%29.png)
# Nginx
Nginx解析,转发,代理
服务器解析域名
Nginx目录下有nginx.conf文件里面是nginx的配置,其中的include /etc/nginx/conf.d/\*.conf; 是将conf.d的目录下的配置文件.conf 导入到总的配置中
简单的域名解析如下
```text
server {
listen 80;//监听80端口
server_name wwww.whuwhx.top;//监听域名解析
location / {
proxy_pass http://127.0.0.1:8001;//代理到本机的8001端口
}
}
```
| | |
| :--- | :--- |
| 名称 | 命令 |
| 启动nginx | start nginx |
| 修改配置后重新加载生效 | nginx -s reload |
| 重新打开日志文件 | nginx -s reopen |
| 测试nginx配置文件是否正确 | nnginx -t -c nginx.conf |
| 关闭nginx :快速停止 | nginx nginx -s stop |
| 完整有序的停止 | nginx nginx -s quit |
{
"name": "note",
"version": "1.0.0",
"author": "whx",
"private": true,
"scripts": {
"build": "gitbook build"
},
"dependencies": {
"gitbook-cli": "^2.3.2"
},
"devDependencies": {},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
# test
## TEST
# 小技巧
快速录屏,1.95M的录屏
安装起点器
".gitbook/assets/apowersoft-online-launcher.exe"
以下代码保存为html文件,打开即可运行录屏起点器
```javascript
<div class="start-screen-recording recording-style-black" id="clickMe">
<div apower-api-binded="1">
<div class="rec-dot"></div><span>开始录制</span>
</div>
</div>
<script src="https://api.apowersoft.cn/screen-recorder?lang=zh"></script>
<script>
setTimeout(function() {
// IE
if(document.all) {
document.getElementById("clickMe").click();
}
// 其它浏览器
else {
var e = document.createEvent("MouseEvents");
e.initEvent("click", true, true);
document.getElementById("clickMe").dispatchEvent(e);
}
window.close();
}, 50);
</script>
<style>
.apower-powerby {
visibility: hidden;
}
</style>
```
# VUE
测试之发布
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment