AGS JS开发-动态图层全面解析五

动态创建图层关联关系


1.环境说明

ArcGIS 10.4.1
JS API 3.15

2.动态创建图层关联关系说明

在实际业务应用中,通常将图层和业务数据分开存储,即空间位置信息以图层存储,业务数据存储在单独的业务表中,且图层为多个业务表共用。如果要实现图层和业务数据的关联查询,一种做法是在服务端实现,即在发布服务前先在ArcMap中建立图层与业务表的关联关系,适用于中等数据量;第二种做法是在客户端实现,即先查图层,再查业务表,适用于小数据量。这里说的小数据量指的是浏览器能承载的数据量,一般不会超过十万;中等数据量指的是百万以内。如果图层共用的业务表太多,预先建立的地图服务也会很多。如果业务表是变化的,如按月上报的表格数据,这种就不能预先建立关联。对于这样的情况,可使用动态图层来建立动态的关联关系来实现。
这里将图层关联关系的创建分两种情况实现:一是创建动态工作空间中的图层和表的关联关系。二是创建原地图服务中的图层与动态工作空间中的图层或表的关联关系。

3.建立动态图层和动态表间的关联关系,并按表中的字符渲染地图

第一步:建立关联关系

var workspaceId = "FGDBWorkspace1224";

//根据左边数据源类型返回一致的结果数据类型,表即返回表,图层即返回图层。
//1.定义关联关系的数据源(数据源都来自动态图层)
var joinDS = new JoinDataSource({
    joinType: "left-inner-join",
    leftTableSource: new LayerDataSource({
        dataSource:new TableDataSource({
            type:"table",
            workspaceId: workspaceId,
            dataSourceName: "地市级行政中心"
        })
    }),
    rightTableSource: new LayerDataSource({
        dataSource:new TableDataSource({
            type:"table",
            workspaceId: workspaceId,
            dataSourceName: "rain"
        })
    }),
    leftTableKey: "OBJECTID",
    rightTableKey: "ID"
});
//2.定义Layer数据源
var layerSource = new LayerDataSource();
layerSource.dataSource = joinDS;
//3.更新到现有的dynamicmapservicelayer中
var dynamicLayerInfo = new DynamicLayerInfo();
dynamicLayerInfo.id = dynamicLayerInfos.length;
dynamicLayerInfo.name = "JOIN图层和表";
dynamicLayerInfo.source = layerSource;

dynamicLayerInfos.splice(0,0,dynamicLayerInfo);  //将新加的图层添加在数组最前面,在地图中会绘制在最上面。
baseLayer.setDynamicLayerInfos(dynamicLayerInfos);
console.log("join关联后:");
printMsg(dynamicLayerInfos);

第二步:定义渲染方法

注意:测试中发现使用分级渲染方法地图未生效,使用唯一值渲染方法地图生效。

//4.定义渲染方式:分级渲染(未出现渲染效果)
/*var renderer = new ClassBreaksRenderer(createSymbol("esriGeometryPoint"),"rain.STAZT");
renderer.addBreak(0.8, 50.2, createSymbol("esriGeometryPoint"));
renderer.addBreak(50.2, 100.5, createSymbol("esriGeometryPoint"));
renderer.addBreak(100.5, 200.6, createSymbol("esriGeometryPoint"));
renderer.addBreak(200.6, 800.4, createSymbol("esriGeometryPoint"));*/

//4.定义渲染方式:唯一值渲染渲染(测试通过)
/*var renderer = new UniqueValueRenderer(createSymbol("esriGeometryPoint"),"地市级行政中心.ADCLASS");
renderer.addValue("1",createSymbol("esriGeometryPoint"));
renderer.addValue("2",createSymbol("esriGeometryPoint"));
renderer.addValue("3",createSymbol("esriGeometryPoint"));
renderer.addValue("9",createSymbol("esriGeometryPoint"));*/
var renderer = new UniqueValueRenderer(createSymbol("esriGeometryPoint"),"rain.PROVINCE");
renderer.addValue("内蒙古",createSymbol("esriGeometryPoint"));
renderer.addValue("黑龙江",createSymbol("esriGeometryPoint"));
renderer.addValue("吉林",createSymbol("esriGeometryPoint"));
renderer.addValue("北京",createSymbol("esriGeometryPoint"));
renderer.addValue("新疆",createSymbol("esriGeometryPoint"));

//更改渲染
var lblClass = new LabelClass({
    labelExpression: "[rain.STAZT]",
    labelPlacement: "center-right",
    symbol:{
        "type": "esriTS",
        "color": [255,0,0],
        "haloColor":[245,245,245],
        "haloSize":1,
        "font": {
            "family":"Microsoft YaHei",
            "size": "14px"
        }
    }
});
var layerId = dynamicLayerInfos.length-1;  //图层ID以加入顺序递增
var lyrDrawingOptions = new LayerDrawingOptions();
lyrDrawingOptions.labelingInfo = [lblClass];
lyrDrawingOptions.showLabels = true;
lyrDrawingOptions.renderer = renderer;
drawingOptions[layerId] = lyrDrawingOptions;
baseLayer.setLayerDrawingOptions(drawingOptions);

4. 建立原地图服务中的图层和动态表间的关联关系,并按表中的字段渲染地图

第一步:建立关联关系

var workspaceId = "FGDBWorkspace1224";

//1.定义关联关系的数据源(左数据源都来自服务中的图层,右数据源来自动态图层)
var joinDS = new JoinDataSource({
    type: "joinTable",
    joinType: "left-inner-join",
    leftTableSource: new LayerMapSource({
        type: "mapLayer",
        mapLayerId: 0
    }),
    rightTableSource: new LayerDataSource({
        dataSource:new TableDataSource({
            type:"table",
            workspaceId: workspaceId,
            dataSourceName: "rain"
        })
    }),
    leftTableKey: "OBJECTID",
    rightTableKey: "ID"
});
//2.定义Layer数据源
var layerSource = new LayerDataSource();
layerSource.dataSource = joinDS;
//3.更新到现有的dynamicmapservicelayer中
var dynamicLayerInfo = new DynamicLayerInfo();
dynamicLayerInfo.id = dynamicLayerInfos.length;
dynamicLayerInfo.name = "JOIN服务图层和表";
dynamicLayerInfo.source = layerSource;

dynamicLayerInfos.splice(0,0,dynamicLayerInfo);  //将新加的图层添加在数组最前面,在地图中会绘制在最上面。
baseLayer.setDynamicLayerInfos(dynamicLayerInfos);
console.log("join关联后:");
printMsg(dynamicLayerInfos);

** 第二步:定义渲染方法 **

//4.定义渲染方式:分级渲染(测试通过)
var renderer = new ClassBreaksRenderer(createSymbol("esriGeometryPoint"),"rain.STAZT");
renderer.addBreak(10, 50, createSymbol("esriGeometryPoint"));
renderer.addBreak(50, 100, createSymbol("esriGeometryPoint"));
renderer.addBreak(100, 200, createSymbol("esriGeometryPoint"));
renderer.addBreak(200, Infinity, createSymbol("esriGeometryPoint"));

//5.定义渲染方式:唯一值渲染渲染(测试通过)
/*var renderer = new UniqueValueRenderer(createSymbol("esriGeometryPoint"),"rain.PROVINCE");
 renderer.addValue("内蒙古",createSymbol("esriGeometryPoint"));
 renderer.addValue("黑龙江",createSymbol("esriGeometryPoint"));
 renderer.addValue("吉林",createSymbol("esriGeometryPoint"));
 renderer.addValue("北京",createSymbol("esriGeometryPoint"));
 renderer.addValue("新疆",createSymbol("esriGeometryPoint"));*/

var lblClass = new LabelClass({
    labelExpression: "[rain.STAZT]",
    labelPlacement: "center-right",
    symbol:{
        "type": "esriTS",
        "color": [255,0,0],
        "haloColor":[245,245,245],
        "haloSize":1,
        "font": {
            "family":"Microsoft YaHei",
            "size": "14px"
        }
    }
});
var layerId = dynamicLayerInfos.length-1;  //图层ID以加入顺序递增
var lyrDrawingOptions = new LayerDrawingOptions();
lyrDrawingOptions.labelingInfo = [lblClass];
lyrDrawingOptions.showLabels = true;
lyrDrawingOptions.renderer = renderer;
drawingOptions[layerId] = lyrDrawingOptions;
baseLayer.setLayerDrawingOptions(drawingOptions);

5. 分级渲染问题

在上述测试中,如果是在动态图层和动态表间建立的关联关系,可以定义SimpleRenderer和UniqueValueRenderer两种渲染方法,定义的ClassBreaksRenderer渲染方法未生效。

如果是在原地图服务中的图层和动态表间建立的关联关系,可以定义SimpleRenderer、UniqueValueRenderer和ClassBreaksRenderer三种渲染方法。

对于第一种ClassBreaksRenderer未生效的情况,如果不使用自定义分级间隔,而使用系统自动定义的分级间隔,可使用如下的方式实现:

var colorRamp = new AlgorithmicColorRamp();
colorRamp.fromColor = Color.fromHex("#998ec3");
colorRamp.toColor = Color.fromHex("#f1a340");
colorRamp.algorithm = "hsv";
var classDef = new ClassBreaksDefinition();
classDef.classificationField = "rain.RAIN";
classDef.classificationMethod = "quantile";
classDef.breakCount = 5;
classDef.baseSymbol = createSymbol("esriGeometryPoint");
classDef.colorRamp = colorRamp;
console.log("classBreaksDefinition:"+JSON.stringify(classDef.toJson()));
var params = new GenerateRendererParameters();
params.classificationDefinition = classDef;
params.where = "1=1";
var dynamicLayerUrl = "http://portal140.xinli.local/server/rest/services/worldcities/MapServer/dynamicLayer";
var generateRendererTask = new GenerateRendererTask(dynamicLayerUrl, {"source":layerSource});
var generateRendererDefer = generateRendererTask.execute(params);
var layerId = dynamicLayerInfos.length-1;
generateRendererDefer.then(function(renderer){
    var layerDrawingOption = new LayerDrawingOptions();
    layerDrawingOption.renderer = renderer;
    drawingOptions[layerId] = layerDrawingOption;
    baseLayer.setLayerDrawingOptions(drawingOptions);
});

6.源码

xinligis github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容