hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

关于ArcGIS的OBJECTID生成战略鄙见

2019-11-18杂谈搜奇网40°c
A+ A-

目次

诉求SDEOBJECTIDArcMap编辑重置OBJECTID

诉求

非GIS专业的职员能够很难明白ArcSDE中的表OBJECTID的重要性,要么总想着本身着手去保护,要么就想直接疏忽它,致使总会涌现OBJECTID的争执,编辑数据报错

下面简朴谈谈对OBJECTID的深刻熟悉,举一反三,协助更多人明白它的内部机制

SDE

ArcGIS家的ArcSDE空间数据库引擎,官方定义去官网,那边有许多,但个人感觉像机翻的,读起来很拗口。SDE就是在数据库中增加一个中间件,如许能够存储和治理空间数据,虽然许多数据库像oracle,mysql,sqlserver等都有自家的治理空间数据战略,但和ArcGIS互通方面差一些,想应用ArcGIS壮大的生态,所以会斟酌运用ArcSDE中间件,假如是ArcGIS的熟手,实在对此也无所谓。空间数据库的实质就是定义了一套操作和治理空间数据的数据模型,就像文本数据范例,数据库定义了对它的支解、兼并、拼接、转换等。只是空间数据会庞杂些,空间关联运算存储等要省事的多。

表面上的表现就是安装了ArcSDE中间件后,会有一个SDE用户,这个用户下就包括对空间数据模型的定义、保护治理,内里有许多治理表、注册表、东西函数等。

OBJECTID

ArcGIS治理的数据表中OBJECTID是一个唯一主键标识,而且与一个序列Sequence对应,(能够明白序列就是一个由初始值,步长,最大值的递增函数),每新增一条数据,序列就会按步长递增生成序号。每每不须要你手动干涉干与,除非你没按人家划定规矩,工资损坏生成机制。

比方有时候我们须要经由历程SQL插进去一条数据,那末OBJECTID黑白空,你须要从序列中猎取。表的OBJECTID和序列的对应能够在SDE用户下的TABLE_REGISTRY找到,像下面如许

select t.registration_id  from  SDE.TABLE_REGISTRY t where Owner='yourowner' and Table_Name='yourtablename';

或许直接挪用sde.gdb_util.next_rowid,它会挪用序列获得nextValue的。

但事变每每没有那末简朴

ArcMap编辑

我们在用ArcMap编辑SDE中空间数据时,像新增,假如直接从序列中猎取,那多用户下就会有锁定。

我们看下sde.gdb_util.next_rowid要领的源码

    owner_l := UPPER(owner_in);
    L_table_name(owner_in,table_in,table_l);
    p_name := UPPER(owner_in||'.'||table_l);

    stmt := 'SELECT registration_id FROM SDE.table_registry '||
            'WHERE owner = :owner_l AND table_name = :table_l';

    OPEN C_gdb FOR stmt USING owner_l,table_l;
    FETCH C_gdb INTO reg_id;
    IF C_gdb%NOTFOUND THEN
      raise_application_error(SDE.sde_util.SE_TABLE_NOREGISTERED,

                              'Class '||p_name||' not registered to the Geodatabase.');
    End If;
    CLOSE C_gdb;

    s_value := SDE.version_user_ddl.next_row_id (owner_l,reg_id);
    return(s_value);

SDE.version_user_ddl.next_row_id的重要源码片断以下,感兴趣的能够研讨下

   BEGIN

      --  See if there are any ids for this table in its pipe.

      pipe_name := 'ArcSDE_IdPipe' || TO_CHAR (registration_id);
      pipe_result := DBMS_PIPE.RECEIVE_MESSAGE (pipe_name,0); 

      IF pipe_result = 0 THEN

         -- Found ids in the pipe, read them.

         DBMS_PIPE.UNPACK_MESSAGE (id_start);
         DBMS_PIPE.UNPACK_MESSAGE (id_count);
         next_id := id_start;
         id_start := id_start + 1;
         id_count := id_count - 1;

      ELSE

         -- Fetch ids from the sequence.  Also get the sequence's
         -- increment by value so we know how many ids we actually got.

         sequence_name := 'R' || TO_CHAR (registration_id);

         select_statement := 'SELECT ' || TO_CHAR(owner) || '.' || sequence_name ||
                             '.NEXTVAL FROM DUAL';
         BEGIN
            EXECUTE IMMEDIATE select_statement INTO  next_id;
         EXCEPTION
            WHEN OTHERS THEN
               raise_application_error (sde_util.SE_NO_SDE_ROWID_COLUMN,
                                        'Unable to find or access sequence ' ||
                                        owner || '.r' || 
                                        TO_CHAR (registration_id));
         END;

         OPEN increment_by_cursor (owner,sequence_name);
         FETCH increment_by_cursor INTO increment_by;
         CLOSE increment_by_cursor;

         id_start := next_id + 1;
         id_count := increment_by - 1;

      END IF;

      -- Write any remaining ids back into the pipe.

      IF id_count > 0 THEN
         DBMS_PIPE.RESET_BUFFER;
         DBMS_PIPE.PACK_MESSAGE (id_start);
         DBMS_PIPE.PACK_MESSAGE (id_count);
         pipe_result := DBMS_PIPE.SEND_MESSAGE (pipe_name,4);
      END IF;

      -- Return the id we found.

      RETURN next_id;

   END next_row_id;

上面重要做了两件事变,起首我们sde.gdb_util.next_rowid时不是设想中的从R序列中直接猎取,而是先去一个特定管道ArcSDE_IdPipe+表序列名中拿,没有再从R序列中猎取,并一次取步长的局限。所以有时候会适得其反的发明获得的nextValue和设想中的不一样。当管道中没有值时才去序列猎取。有时候OBJECTID已紊乱(新增报错OBJECTID反复),我们只调解序列的当前值不足以解决问题,管道中猎取的值能够照样小于序列值的,能够致使背面照样反复。所以发起更新时,先清空管道,让第一次读取就从序列中读取。

管道用于多会话之间传递信息。

重置OBJECTID

假如OBJECTID已紊乱,假如准确重置?我们以至遇到过,当检察oracle中OBJECTID范例是INT,INT最大数才2147483648,现实内里居然存储却远大于这个数。查阅oracle文档会发明,底层oracle存储int是映射到number的,所以局限会大许多。但这也给我们提了醒,OBJECTID天然增进怎么会增进到远超2147483648,我们平常不会在一个内外放几十亿,几百亿的数据量吧。这能够就是乱花或疏忽OBJECTID生成战略带来的小坑。

基于以上的解读,重置OBJECTID的基础流程应该是:清空管道,更新OBJECTID,更新序列。在oracle中写了一个存储历程以供参考,源码以下:

年岁大了,记性不好,纪录一下,轻易查阅

刚说什么来着?emmmmmm,对,源码

create or replace procedure P_ResetObjectID(owner in NVARCHAR2, tablename in NVARCHAR2)
is
/*
重置sde table objectID
*/

reg_id         pls_integer;
owner_l        VARCHAR2(64);
table_l        VARCHAR2(64);
pipe_name         VARCHAR2(30);
max_id           NUMBER;
stmt           varchar2(512);
sequence_name     VARCHAR2(64);
begin
    owner_l := UPPER(owner);
    table_l := UPPER(tablename);

    stmt := 'SELECT registration_id FROM SDE.table_registry '||
            '
WHERE owner ='''|| owner_l ||''' AND table_name = '''|| table_l ||'''';
    EXECUTE IMMEDIATE stmt INTO  reg_id;
    if reg_id is null then return;
    end if;
    pipe_name := '
ArcSDE_IdPipe' || TO_CHAR (reg_id);
    --消灭arcgis缓存管道
    stmt := '
select sys.dbms_pipe.remove_pipe('''||pipe_name||'''from dual ';
    EXECUTE IMMEDIATE stmt;
    --更新oid
    stmt := '
update '||table_l||' set objectid=rownum ';
    EXECUTE IMMEDIATE stmt;
    --猎取最大oid
    stmt := '
select max(objectid)  from '||table_l;
    EXECUTE IMMEDIATE stmt INTO  max_id;
    if max_id is NULL then return;
    end if;
    --修正序列的当前值
    sequence_name := '
R' || TO_CHAR (reg_id);
    stmt := '
drop  sequence '||sequence_name||' ';
    EXECUTE IMMEDIATE stmt;
    stmt := '
create sequence '||sequence_name||' minvalue 1 maxvalue 2147483647 start with '||max_id||' increment by 16 cache 20';
    EXECUTE IMMEDIATE stmt;
    stmt := '
grant select on '||owner_l||'.'||sequence_name||' to public';
    EXECUTE IMMEDIATE stmt;
end P_ResetObjectID;

手机在手边,可关注vx:xishaobb,互动或猎取更多信息,迎接交换斧正,固然这里也一向更新de,有缘见,拜了个拜拜

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
关于ArcGIS的OBJECTID生成战略鄙见

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282335.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>