通過openlayers載入dwg格式的CAD圖並與互聯網地圖疊加

来源:https://www.cnblogs.com/vjmap/archive/2022/10/16/16797277.html
-Advertisement-
Play Games

Openlayers介紹 ​ Openlayers是一個基於Javacript開發,免費、開源的前端地圖開發庫,使用它,可以很容易的開發出WebGIS系統。目前Openlayers支持地圖瓦片、矢量數據等眾多地圖數據格式,支持比較完整的地圖交互操作。目前OpenLayers已經成為一個擁有眾多開發者 ...


Openlayers介紹

​ Openlayers是一個基於Javacript開發,免費、開源的前端地圖開發庫,使用它,可以很容易的開發出WebGIS系統。目前Openlayers支持地圖瓦片、矢量數據等眾多地圖數據格式,支持比較完整的地圖交互操作。目前OpenLayers已經成為一個擁有眾多開發者和幫助社區的成熟、流行的框架,在國內外的GIS相關行業中得到了廣泛的應用。

openlayers 官網地址 https://openlayers.org/

openlayers 源碼地址 https://github.com/openlayers/openlayers

Openlayers中載入CAD柵格瓦片

image-20221016204713951

// 地圖服務對象,調用唯傑地圖服務打開地圖,獲取地圖的元數據
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)
// 打開地圖
let mapId = "sys_zp";
let res = await svc.openMap({
    mapid: mapId, // 地圖ID
    mapopenway: vjmap.MapOpenWay.GeomRender, // 以幾何數據渲染方式打開
    style: vjmap.openMapDarkStyle() // div為深色背景顏色時,這裡也傳深色背景樣式
})
if (res.error) {
    // 如果打開出錯
    message.error(res.error)
}
// 獲取地圖範圍
let mapBounds = vjmap.GeoBounds.fromString(res.bounds);

//自定義投影參數
let cadProjection = new ol.proj.Projection({
    // extent用於確定縮放級別
    extent: mapBounds.toArray(),
    units: 'm'
});
// 設置每級的解析度
let resolutions= [];
for(let i = 0; i < 25; i++) {
    resolutions.push(mapBounds.width() / (512 * Math.pow(2, i - 1)))
}
// 增加自定義的cad的坐標系
ol.proj.addProjection(cadProjection);

// 創建openlayer的地圖對象
let map = new ol.Map({
    target: 'map', // div的id
    view: new ol.View({
        center: mapBounds.center().toArray(),  // 地圖中心點
        projection: cadProjection, // 剛自定義的cad的坐標系
        resolutions:resolutions, // 解析度
        zoom: 2// 初始縮放級別
    })
});

// 增加一個瓦片圖層
let layer = new ol.layer.Tile({
    // 增加一個瓦片數據源
    source: new ol.source.TileImage({
        url: svc.rasterTileUrl() // 唯傑地圖服務提供的cad的柵格瓦片服務地址
    })
});
// 在地圖中增加上面的瓦片圖層
map.addLayer(layer);

Openlayers中載入CAD矢量瓦片


// 增加一個矢量瓦片圖層
let layer = new ol.layer.VectorTile({
    // 增加一個瓦片數據源
    source: new ol.source.VectorTile({
        projection: cadProjection,
        format: new ol.format.MVT(),
        url: svc.vectorTileUrl() // 唯傑地圖服務提供的cad的矢量瓦片服務地址
    }),
    style: createVjMapVectorStyle(ol.style.Style, ol.style.Fill, ol.style.Stroke, ol.style.Circle)
});
// 在地圖中增加上面的瓦片圖層
map.addLayer(layer);

Openlayers中選擇高亮CAD實體

olselectHighlight.gif


const highlight_ent = async co => {
    vectorSource.clear();
    let res = await svc.pointQueryFeature({
        x: co[0],
        y: co[1],
        zoom: map.getView().getZoom(),
        fields: ""
    }, pt => {
        // 查詢到的每個點進行坐標處理回調
        return mapPrj.fromMercator(pt);// 轉成cad的坐標
    })
    if (res && res.result && res.result.length > 0) {
        let features = [];
        for (let ent of res.result) {
            if (ent.geom && ent.geom.geometries) {
                let clr = vjmap.entColorToHtmlColor(ent.color);
                for (let g = 0; g < ent.geom.geometries.length; g++) {
                    features.push({
                        type: "Feature",
                        properties: {
                            objectid: ent.objectid + "_" + g,
                            color: clr,
                            alpha: ent.alpha / 255,
                            lineWidth: 1,
                            name: ent.name,
                            isline: ent.isline,
                            layerindex: ent.layerindex
                        },
                        geometry: ent.geom.geometries[g]
                    })
                }
                // 選擇提示
                let content = `feature: ${ent.objectid}; layer: ${cadLayers[ent.layerindex].name}; type: ${ent.name}`
                message.info({ content, key: "info", duration: 3});
            }
        }
        geojsonObject.features = features;
        if (geojsonObject.features.length > 0) {
            vectorSource.addFeatures( new ol.format.GeoJSON().readFeatures(geojsonObject, {dataProjection: cadProjection}))
        }
    }
};

Openlayers中上傳打開CAD的DWG圖形

oluploadmap.gif


// 地圖服務對象,調用唯傑地圖服務打開地圖,獲取地圖的元數據
let svc = new vjmap.Service(env.serviceUrl, env.accessToken)

// 上傳dwg文件
const uploadDwgFile = async file => {
    message.info("正在上傳圖形,請稍候", 2);
    let res = await svc.uploadMap(file); // 上傳地圖
    // 輸入圖id
    let mapid = prompt("請輸入圖名稱ID", res.mapid);
    res.mapid = mapid;
    res.mapopenway = vjmap.MapOpenWay.GeomRender; // 幾何渲染,記憶體渲染用vjmap.MapOpenWay.Memory
    res.isVector = false; // 使用柵格瓦片
    res.style = vjmap.openMapDarkStyle(); // 深色樣式,淺色用openMapDarkStyle
    message.info("正在打開圖形,請稍候,第一次打開時根據圖的大小可能需要幾十秒至幾分鐘不等", 5);
    let data = await svc.openMap(res); // 打開地圖
    if (data.error) {
        message.error(data.error)
        return;
    }
    openMap(data);
}

Openlayers中切換CAD圖層

olswitchlayer.gif

// 切換圖層
const switchLayer = async layers => {
    let res = await svc.cmdSwitchLayers(layers); // 調用唯傑服務切換圖層,返回圖層id {layerid: "xxxx"}
    let source = layer.getSource();
    // 重新設置新的唯傑地圖服務提供的cad的柵格瓦片服務地址
    source.setUrl(svc.rasterTileUrl());
    // 刷新
    source.refresh();
}

Openlayers中切換CAD圖形

olswitchmap.gif


const switchToMapId = async (mapId)=> {
    let res = await svc.openMap({
        mapid: mapId, // 地圖ID
        mapopenway: vjmap.MapOpenWay.GeomRender, // 以幾何數據渲染方式打開
        style: vjmap.openMapDarkStyle() // div為深色背景顏色時,這裡也傳深色背景樣式
    })
    if (res.error) {
        // 如果打開出錯
        message.error(res.error)
        return;
    }
// 獲取地圖範圍
    let mapBounds = vjmap.GeoBounds.fromString(res.bounds);

//自定義投影參數
    let cadProjection = new ol.proj.Projection({
        // extent用於確定縮放級別
        extent: mapBounds.toArray(),
        units: 'm'
    });
// 設置每級的解析度
    let resolutions= [];
    for(let i = 0; i < 25; i++) {
        resolutions.push(mapBounds.width() / (512 * Math.pow(2, i - 1)))
    }
// 增加自定義的cad的坐標系
    ol.proj.addProjection(cadProjection);

// 重新創建openlayer的地圖對象
    map = new ol.Map({
        target: createNewMapDivId(), // div的id
        view: new ol.View({
            center: mapBounds.center().toArray(),  // 地圖中心點
            projection: cadProjection, // 剛自定義的cad的坐標系
            resolutions:resolutions, // 解析度
            zoom: 2 // 初始縮放級別
        })
    });

// 增加一個瓦片圖層
    let layer = new ol.layer.Tile({
        // 增加一個瓦片數據源
        source: new ol.source.TileImage({
            url: svc.rasterTileUrl() // 唯傑地圖服務提供的cad的柵格瓦片服務地址
        })
    });
// 在地圖中增加上面的瓦片圖層
    map.addLayer(layer);

    map.on('click', (e) => message.info({content: `您點擊的坐標為: ${JSON.stringify(e.coordinate)}`, key: "info", duration: 3}));
}

Openlayers中深色淺色切換主題

image-20221016210550215

let curIsDarkTheme = true;
const switchToDarkTheme = async () => {
    if (curIsDarkTheme) return;
    curIsDarkTheme = true;
    document.body.style.background = "#022B4F"; // 背景色改為深色
    await updateStyle(curIsDarkTheme)
}

const switchToLightTheme = async () => {
    if (!curIsDarkTheme) return;
    curIsDarkTheme = false;
    document.body.style.backgroundImage = "linear-gradient(rgba(255, 255, 255, 1), rgba(233,255,255, 1), rgba(233,255,255, 1))"
    await updateStyle(curIsDarkTheme)
}

const updateStyle = async (isDarkTheme) => {
    style.backcolor = isDarkTheme ? 0 : 0xFFFFFF;//深色為黑色,淺色為白色
    let res = await svc.cmdUpdateStyle(style);
    let source = layer.getSource();
    // 重新設置新的唯傑地圖服務提供的cad的柵格瓦片服務地址
    source.setUrl(svc.rasterTileUrl());
    // 刷新
    source.refresh();
}

Openlayers中自定義CAD地圖樣式

通過修改CAD地圖後臺樣式數據自定義地圖

olcustommapstyle.gif


// 更改樣式
const expressionList = [] ;// 表達式數組
const updateStyle = async (style) => {
    let res = await svc.cmdUpdateStyle({
        name: "customStyle2",
        backcolor: 0,
        expression: expressionList.join("\n"),
        ...style
    });
    let source = layer.getSource();
    // 重新設置新的唯傑地圖服務提供的cad的柵格瓦片服務地址
    source.setUrl(svc.rasterTileUrl());
    // 刷新
    source.refresh();
}

// 表達式語法和變數請參考
// 服務端條件查詢和表達式查詢 https://vjmap.com/guide/svrStyleVar.html
// 服務端渲染表達式語法 https://vjmap.com/guide/expr.html

// 修改顏色  紅color.r, 綠color.g, 藍color.b, 透明度color.a,如果輸入了級別的話,表示此級別及以上的設置
const modifyColor = (color, zoom) => {
    let result = "";
    let z = Number.isInteger(zoom) ? `[${zoom + 1}]` : '';
    if ("r" in color) result += `gOutColorRed${z}:=${color.r};`;
    if ("g" in color) result += `gOutColorGreen${z}:=${color.g};`;
    if ("b" in color) result += `gOutColorBlue${z}:=${color.b};`;
    if ("a" in color) result += `gOutColorAlpha${z}:=${color.a};`;
    return result;
}

Openlayers中對CAD圖處理組合

對多個cad圖進行圖層開關裁剪旋轉縮放處理後合併成一個新的cad圖

image-20221016210950391


// 組合成新的圖,將sys_world圖進行一定的處理後,再與sys_hello進行合成,生成新的地圖文件名
let rsp = await svc.composeNewMap([
    {
        mapid: "sys_world", // 地圖id
        // 下麵的參數可以根據實際需要來設置,可以對圖層,範圍,坐標轉換來進行處理
        layers: ["經緯度標註","COUNTRY"], // 要顯示的圖層名稱列表
        //clipbounds: [10201.981489534268, 9040.030491346213, 26501.267379,  4445.465999], // 要顯示的範圍
        //fourParameter: [0,0,1,0] // 對地圖進行四參數轉換計算
    },
    {
        mapid: "sys_hello"
    }
])
if (!rsp.status) {
    message.error(rsp.error)
}
// 返回結果為
/*
{
    "fileid": "pec9c5f73f1d",
    "mapdependencies": "sys_world||sys_hello",
    "mapfrom": "sys_world&&v1&&&&0&&&&&&&&&&00A0&&10||sys_hello&&v1&&&&0&&&&&&&&&&&&2",
    "status": true
}
 */

Openlayers中查詢圖中所有文字並繪製邊框

olfindtextdrawbounds.gif


// 實體類型ID和名稱映射
const { entTypeIdMap } = await svc.getConstData();
const getTypeNameById = name => {
    for(let id in entTypeIdMap) {
        if (entTypeIdMap[id] == name) {
            return id
        }
    }
}
const queryTextAndDrawBounds = async () => {
    let queryTextEntTypeId = getTypeNameById("AcDbText"); // 單行文字
    let queryMTextEntTypeId = getTypeNameById("AcDbMText"); // 多行文字
    let queryAttDefEntTypeId = getTypeNameById("AcDbAttributeDefinition"); // 屬性定義文字
    let queryAttEntTypeId = getTypeNameById("AcDbAttribute"); // 屬性文字
    let query = await svc.conditionQueryFeature({
        condition: `name='${queryTextEntTypeId}' or name='${queryMTextEntTypeId}' or name='${queryAttDefEntTypeId}' or name='${queryAttEntTypeId}'`, // 只需要寫sql語句where後面的條件內容,欄位內容請參考文檔"服務端條件查詢和表達式查詢"
        fields: "",
        limit: 100000 //設置很大,相當於把所有的圓都查出來。不傳的話,預設只能取100條
    }, pt => {
        // 查詢到的每個點進行坐標處理回調
        return mapPrj.fromMercator(pt);// 轉成cad的坐標
    })
    if (query.error) {
        message.error(query.error)
    } else {
        message.info(`查詢到符合的記數條數:${query.recordCount}`)

        if (query.recordCount > 0) {
            let features = [];
            for(var i = 0; i < query.recordCount; i++) {
                let bounds = vjmap.getEnvelopBounds(query.result[i].envelop, mapPrj);
                let clr = vjmap.entColorToHtmlColor(query.result[i].color); // 實體顏色轉html顏色(

                features.push({
                    type: "Feature",
                    properties: {
                        name: "objectid:" + query.result[i].objectid,
                        color: clr
                    },
                    geometry: {
                        'type': 'Polygon',
                        'coordinates': [
                            bounds.toPointArray(),
                        ],
                    }
                })
            }

            if (!vectorSource) {
                // 如果之前沒有高亮矢量圖層
                addHighLightLayer();
            }
            vectorSource.clear();
            let geojsonObject = {
                'type': 'FeatureCollection',
                'features': features
            }
            // 修改矢量數據源數據
            vectorSource.addFeatures( new ol.format.GeoJSON().readFeatures(geojsonObject, {dataProjection: cadProjection}))
        }
    }
}

Openlayers中圖形繪製

image-20221016211331840


const source = new ol.source.Vector({wrapX: false});

const vector = new ol.layer.Vector({
    source: source,
});

map.addLayer(vector);

let draw; // global so we can remove it later
function addInteraction(value) {
    map.removeInteraction(draw);
    if (value !== 'None') {
        draw = new ol.interaction.Draw({
            source: source,
            type: value,
        });
        map.addInteraction(draw);
    }
}

addInteraction('Point');

Openlayers中CAD圖疊加互聯網地圖[CAD為底圖]

olwebCad.gif


// 增加高德地圖底圖
let gdlayer;
const addGaodeMap = async (isRoadway) => {
    const tileUrl = svc.webMapUrl({
        tileCrs: "gcj02",
        tileUrl:  isRoadway ? [
                "https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"
            ] :
            /* 如果用影像 */
            [
                "https://webst0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=6&x={x}&y={y}&z={z}",
                "https://webst0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"
            ],
        tileSize: 256,
        tileRetina: 1,
        tileMaxZoom: 18,
        tileShards: "1,2,3,4",
        tileToken: "",
        tileFlipY: false,
        mapbounds: res.bounds,
        srs: "EPSG:4527",// 可通過前兩位獲取 vjmap.transform.getEpsgParam(vjmap.transform.EpsgCrsTypes.CGCS2000, 39).epsg
        // 因為sys_cad2000這個圖只有6位,沒有帶系。需要在坐標轉換前平移下帶系  https://blog.csdn.net/thinkpang/article/details/124172626
        fourParameterBefore: "39000000,0,1,0"
    })


    // 增加一個瓦片圖層
    gdlayer = new ol.layer.Tile({
        // 增加一個瓦片數據源
        source: new ol.source.TileImage({
            url: tileUrl
        })
    });
    gdlayer.setZIndex(-1);
// 在地圖中增加上面的瓦片圖層
    map.addLayer(gdlayer);


    // cad坐標與高德坐標相互轉換示例
    let webCo = await cad2webCoordinate(center, false); // cad轉高德
    let cadCo = await web2cadCoordinate(webCo, false); // 高德轉cad
    console.log(center, webCo, cadCo)
}

Openlayers中互聯網地圖自動疊加CAD圖[互聯網圖為底圖]

image-20221016211820059


let cadEpsg = "EPSG:4544";// cad圖的espg代號
// 增加cad的wms圖層
let wmsUrl = svc.wmsTileUrl({
    mapid: mapId, // 地圖id
    layers: layer, // 圖層名稱
    bbox: '', // bbox這裡不需要
    srs: "EPSG:3857", //
    crs: cadEpsg
})
function getQueryStringArgs(url) {
    let theRequest = {};
    let idx = url.indexOf("?");
    if (idx != -1) {
        let str = url.substr(idx + 1);
        let strs = str.split("&");
        for (let i = 0; i < strs.length; i++) {
            let items = strs[i].split("=");
            theRequest[items[0]] = items[1];
        }
    }
    return theRequest;
}

let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
// cad圖坐標轉web wgs84坐標
const cadToWebCoordinate = async point => {
    let co = await svc.cmdTransform(cadEpsg, "EPSG:4326", point);
    return co[0]
}
// cad轉wgs84經緯度
let boundsMin = await cadToWebCoordinate(mapBounds.min);
let boundsMax = await cadToWebCoordinate(mapBounds.max);
// wgs84經緯度轉墨卡托
boundsMin = vjmap.Projection.lngLat2Mercator(boundsMin);
boundsMax = vjmap.Projection.lngLat2Mercator(boundsMax);

// 在openlayer中增加wms圖層
map.addLayer(new ol.layer.Tile({
    // 範圍
    extent: [boundsMin[0], boundsMin[1], boundsMax[0], boundsMax[1]],
    source: new ol.source.TileWMS({
        url: wmsUrl.substr(0, wmsUrl.indexOf("?")),
        params: {...getQueryStringArgs(wmsUrl),'TILED': true}
    }),
}))

Openlayers中互聯網地圖公共點疊加CAD圖[互聯網圖為底圖]

olCadFourparam.gif


// cad上面的點坐標
let cadPoints = [
    vjmap.geoPoint([587464448.8435847, 3104003685.208651,]),
    vjmap.geoPoint([587761927.7224838, 3104005967.655292]),
    vjmap.geoPoint([587463688.0280377, 3103796743.3798513]),
    vjmap.geoPoint([587760406.0913897, 3103793700.1176634])
];

// 在互聯網圖上面拾取的與上面的點一一對應的坐標(wgs84坐標)
let webPoints = [
    vjmap.geoPoint([116.48476281710168, 39.96200739703454]),
    vjmap.geoPoint([116.48746772021137, 39.96022062215167]),
    vjmap.geoPoint([116.48585059441585, 39.9588451134361]),
    vjmap.geoPoint([116.48317418949145, 39.960515760972356])
]
// 通過坐標參數求出四參數
let epsg3857Points = webPoints.map(w => vjmap.geoPoint(vjmap.Projection.lngLat2Mercator(w)));
let param = vjmap.coordTransfromGetFourParamter(epsg3857Points, cadPoints , false); // 這裡考慮旋轉
let fourparam = [param.dx, param.dy, param.scale, param.rotate]

// wms圖層地址
const getCadWmsUrl = (transparent) => {
    let wmsUrl = svc.wmsTileUrl({
        mapid: mapId, // 地圖id
        layers: layer, // 圖層名稱
        bbox: '', // bbox這裡不需要
        fourParameter: fourparam,
        transparent: transparent,
        backgroundColor: 'rgba(240, 255, 255)' // 不透明時有效
    })
    return wmsUrl
}

let mapBounds = vjmap.GeoBounds.fromString(res.bounds);
let cadPrj = new vjmap.GeoProjection(mapBounds);


// cad圖坐標轉3857坐標
const cadToWebCoordinate = point => {
    // 再調用四參數反算求出web的坐標
    return vjmap.coordTransfromByInvFourParamter(vjmap.geoPoint(point), param)
}
// 3857轉cad圖坐標
const webToCadCoordinate = point => {
    return vjmap.coordTransfromByFourParamter(vjmap.geoPoint(point), param)
}

let wmsLayer;
const addWmsLayer = async (transparent)=> {
    removeWmsLayer();
    let wmsUrl = getCadWmsUrl(transparent);
    wmsLayer = new ol.layer.Tile({
        // 範圍
        extent: bounds.toArray(),
        source: new ol.source.TileWMS({
            url: wmsUrl.substr(0, wmsUrl.indexOf("?")),
            params: {...getQueryStringArgs(wmsUrl),'TILED': true}
        }),
    });
    // 在openlayer中增加wms圖層
    map.addLayer(wmsLayer);
}

最後

可點擊 https://vjmap.com/demo/#/demo/map/openlayers/01olraster 線上體驗上面功能

如果需要用openlayers來載入CAD圖進行開發,請參考示例 https://vjmap.com/demo/#/demo/map/openlayers/01olraster

如果需要用leaflet來載入CAD圖進行開發,請參考示例 https://vjmap.com/demo/#/demo/map/leaflet/01leafletraster

如果需要用maptalks來載入CAD圖進行開發,請參考示例 https://vjmap.com/demo/#/demo/map/maptalks/01maptalksraster

如何基於vue3來開發openlayers應用,可查看此開源代碼 https://github.com/MelihAltintas/vue3-openlayers

如何基於vue2來開發openlayers應用,可查看此開源代碼 https://github.com/ghettovoice/vuelayers


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • WPF以其豐富靈活的控制項樣式設計,相較於WinForm而言,一直是工控組態軟體的寵兒,本文以兩個簡單的小例子,簡述如何通過WPF設計出表示水流的管道,和轉動的冷卻風扇。僅供學習分享使用,如有不足之處,還請指正。 ...
  • LAMP架構 LAMP架構的組成: LAMP架構的工作原理: 說明: 訪問動態資源的時候,apache就是個異構代理伺服器,接收並轉發用戶的請求。通過CGI或者fastcgi介面將請求轉發給php解釋器。 apache請求轉發的時候可能會涉及到跨網路轉發,跨網路轉發使用fastcgi來實現。 異構代 ...
  • nginx配置文件rewrite和if rewrite 語法:rewrite regex replacement flag;,如: rewrite ^/images/(.*\.jpg)$ /imgs/$1 break; 此處的$1用於引用(.*.jpg)匹配到的內容,又如: rewrite ^/bb ...
  • 1、下載安裝包(官網下載) 直達鏈接:https://dev.mysql.com/downloads/mysql/ 下載後放到指定目錄下解壓即可(給電腦新手忠告:註意不要放在C盤,養成好習慣,放C盤多了會影響電腦運行速度) 像我放D盤: 2、安裝過程 2.1、配置環境 變數名:MYSQL_HOME ...
  • 隨著系統運行時間的推移,資料庫日誌文件會變得越來越大,這時我們需要對日誌文件進行備份或清理。 解決方案1 - 直接刪除本地ldf日誌文件:(比較靠譜方案!) 1. 在SQL管理器分離資料庫。 2. 對資料庫日誌文件進行壓縮備份(rar, zip) 3. 直接刪除ldf文件。 4. 再附加資料庫。若出 ...
  • MongoDB 是一個強大的分散式存儲引擎,天然支持高可用、分散式和靈活設計。MongoDB 的一個很重要的設計理念是:服務端只關註底層核心能力的輸出,至於怎麼用,就儘可能的將工作交個客戶端去決策。這也就是 MongoDB 靈活性的保證,但是靈活性帶來的代價就是使用成本的提升。與 MySql 相比,... ...
  • 我們在安卓開發學習中會遇到需要返回數據的情況,這裡我們使用了幾個方法 1、startActivityForResult通過這個方法我們可以啟動另外一個活動 2、onBasePressed使用這個方法我們可以 點擊返回鍵返回數據到上一個活動 3、onActivityResult我們在需要接收返回數據的 ...
  • 語法規範 JavaScript嚴格區分大小寫,對空格、換行、縮進不敏感,建議語句結束加‘;’ JavaScript 會忽略多個空格。您可以向腳本添加空格,以增強可讀性。 JavaScript 程式員傾向於使用以小寫字母開頭的駝峰大小寫 firstName, lastName, masterCard, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...