BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
arthurdpereira
Fluorite | Level 6

Fala pessoal, tudo bem?

Será que alguém poderia me ajudar ou me ensinar de como fazer, pois estou já há algumas horas nesse código.

Estou usando o SAS Viya V.03.05.

Eu tenho esse código que já conseguir meio que andar com ele:

/* Realizar o Download do Arquivo GeoJSON do Github */
filename mapa temp;

proc http
    url="https://raw.githubusercontent.com/tbrugz/geodata-br/master/geojson/geojs-32-mun.json"
    method="GET"
    out=mapa;
run;

/* Ler o Arquivo GeoJSON usando a Biblioteca JSON */
libname jsonlib json fileref=mapa;

/* Examinar a Estrutura do GeoJSON */
proc contents data=jsonlib._all_;
run;

Até aqui, vai bem. O código cria as tabelas do GeoJSON separadas, porém, eu não faço ideia de como linkar isso em um mapa Polígono.. 

Eu também gostaria de uma ajuda para colocar isso no VA, qual tabela e o passo a passo de como eu poderia fazer.. Se possível é claro.

https://prnt.sc/e2I_ecsENtu_

 

1 ACCEPTED SOLUTION

Accepted Solutions
arthurdpereira
Fluorite | Level 6

Agradeço a todos pela tentativa de me ajudar a solucionar o meu problema, porém, o link que mais me deu entendimento detalhado de como fazer foi esse:
https://blogs.sas.com/content/sgf/2018/01/26/how-to-create-custom-regional-maps-in-sas-visual-analyt...

O código, no final, ficou dessa forma:

/* Fazer o Download do Arquivo GeoJSON do Github */
filename mapa temp;

proc http
	url="https://raw.githubusercontent.com/tbrugz/geodata-br/master/geojson/geojs-32-mun.json"
	method="GET"
	out=mapa;
run;

/* Ler o Arquivo GeoJSON usando a Biblioteca JSON */
libname jsonlib json fileref=mapa;

/* Examinar a Estrutura do GeoJSON */
proc contents data=jsonlib._all_;
run;

/* Unir as tabelas */
data map_data;
    merge jsonlib.features_properties 
          jsonlib.features_geometry (keep=ordinal_features ordinal_geometry type);
    by ordinal_features;
run;

/* Preparar os dados para o gráfico GMAP */
data map_data;
    merge map_data
          jsonlib.geometry_coordinates;
    by ordinal_geometry;
run;

/* Preparar os dados para a Plotagem */
data plot_data (drop=element1 element2);
    set map_data;
    x = element1;
    y = element2;
    i = 1;
    output;
run;

/* Plotar o gráfico */
proc gmap data=plot_data map=plot_data;
    id name;
    choro name / nolegend levels=1;
run;

/*A partir daqui, são passos para disponibilizar a tabela no CAS e consequentemente disponibilizar no VA*/
%macro sas_load_data_cas(incaslib=,casdata=,data=,outcaslib=, casout=);
/*Deleta tabela "in-memory"*/
proc casutil;
droptable incaslib = "&outcaslib." casdata = "&casdata." quiet;
run;

/*Carrega tabela no  CAS*/
proc casutil;
  load data=&data. casout="&casout." outcaslib=&outcaslib. replace;
quit;

/* Promove a tabela para uma "global session" (disponivel para todos os usuário acesso ao servidor) */
proc casutil;
promote incaslib = "&outcaslib." casdata = "&casdata."
outcaslib = "&outcaslib." casout = "&casout.";
quit;
%mend sas_load_data_cas;
%sas_load_data_cas(incaslib=Public,casdata=PLOT_MAPA,data=WORK.PLOT_DATA,outcaslib=Public, casout=PLOT_MAPA)

Depois daqui, basta seguir os passos do link a partir do Step 8, sendo o i=segmento.

View solution in original post

5 REPLIES 5
wilkoba
SAS Employee

Bom @arthurdpereira ,

 

Não sei qual versão de SAS e Visual Analytics você esta utilizando. Seguem aqui alguns artigos que podem te ajudar a fazer esta importação de dados.

1. Explicação de como o Visual Analytics funciona com maps e referências de maps: Essentials of Map Coordinate Systems and Projections in Visual Analytics - SAS Users]

2. Como importar mapas para dentro do SAS Viya: SAS Help Center: Loading Geographic Polygon Data as a CAS Table se utiliza SAS9 com Visual Analytics no SAS9 deve ter também sua macra para importar os mapas

3.  Como importar um shapefile para dentro do Visual Analytics: 

How do I import a shape file(.shp) in SAS Viya Visual Analytics? - SAS Support Communities

4. Como os polígonos são tratados e reconhecidos dentro do SAS

Leverage Custom Geographical Polygons in SAS® Visual Analytics

 

Espero que as referências te ajudem.

 

 

arthurdpereira
Fluorite | Level 6

Eu uso o SAS VA 8.5.2.

Eu já tentei esses arquivos, mas eles se referem todos a um mapa dos EUA. 

wilkoba
SAS Employee

@arthurdpereira , entendo sua preocupação

 

Espero que ajude, tenho um exemplo carregando um shapefile com dados do México, talvez te ajude como referência de como fazer.

 

/************************************************

SAS Visual Analytics Custom Polygon Deployment Program

Use this program to import custom polygons from an Esri SHP file for use in SAS Visual Analytics.
Before running, define the two Librefs and the block of macro variables at the top of this program, 
and then modify Step 2 if needed to ensure that the values of the IDLABEL (IDNAME) column are unique.

For details, see the SAS Visual Analytics 7.4: Administration Guide at support.sas.com.

************************************************/

/* ====== Update the following code: ===== */

libname MAPSCSTM "D:\opt\sasinside\SASHome\SASFoundation\9.4\mapscstm"; /* The library containing the custom polygon data (For example, C:\Data\mapscstm) */
libname VALIB "D:\opt\sasinside\Config\Lev1\SASApp\Data\valib"; /* The library containing the Visual Analytics lookup tables (For example, C:\SAS\VA\Lev1\SASApp\Data\valib) */
%let REGION_LABEL=Mexico States from Shapefile; /* The label for the custom region (For example, My Sales Regions) */
%let REGION_PREFIX=M1; /* unique ISO 2-Letter Code - make sure it doesn't conflict with any code! (For example, CS). You can run a query in attrlookup to check availability */
%let REGION_ISO=000; /* unique ISO Code - make sure it doesn't conflict with any other code! (For example, 000). You can run a query in attrlookup to check availability */
%let REGION_DATASET=MAPSCSTM.MX_STATES_SHP1; /* Name of the polygon data set to be created - be sure to use suffix "1" (For example, MAPSCSTM.MYSALESREGION1) */
%let REGION_SHP_FILE=D:\Mexico_States\Mexico_States.shp; /* Source polygon file in Esri SHP format (For example, C:\Data\myregion.shp) */
%let REGION_SHP_ID_COL=CODE; /* the column representing the unique ID of a polygon (For example, ID). You can find it after running PROC MAPIMPORT below */
%let REGION_SHP_NAME_COL=NAME; /* the column representing the name of the polygon (For example, NAME). You can find it after running PROC MAPIMPORT below  */
%let REGION_SHP_DENSITY=7; /* Value between 1 (low) - 10 (high) describing the detail level/density. (For example, 3) */

/* ====== End code updates -- Also see the section marked as Step 2 below ===== */

/* Utility macro to stop processing in case of any validation errors */
%let ERROR_COUNT=0; /* 0 indicates no error */
%let ERROR_MESSAGE=;

%MACRO ErrorTest;
   %GLOBAL ERROR_COUNT;

   %IF &ERROR_COUNT gt 0 %THEN
      %DO;
         %PUT ERROR: &ERROR_MESSAGE;

         %abort cancel;
         %let ERROR_COUNT=0; /* reset */
      %END;
%MEND;

/* [BACKUP] Create a backup of the original lookup tables if required */
%macro backupLookupTable(dsn);
   %if %sysfunc(exist(&dsn._original)) %then
      %do;
         %put INFO: Backup table &dsn found.;
      %end;
   %else
      %do;

         data &dsn._original;
            set &dsn;
         run;

      %end;
%mend backupLookupTable;

%backupLookupTable(valib.attrlookup);
%backupLookupTable(valib.centlookup);

/* [VALIDATION STEP] Check for unique 2-letter ISO code */
proc sql noprint;
   /* count and create error code if greater than zero */
   select count(ID) as count,
      case 
         when calculated count > 0 then "2-letter ISO code &REGION_PREFIX. is not unique in ATTRLOOKUP. Please specify a different code."
         else "" 
      end
   into :ERROR_COUNT, :ERROR_MESSAGE
      from valib.attrlookup_original
         where upcase(ID) eq upcase("&REGION_PREFIX.");
quit;

%ErrorTest;

/* [VALIDATION STEP] Check for unique ISO code */
proc sql noprint;
   /* count and create error code if greater than zero */
   select count(ISO) as count,
      case 
         when calculated count > 0 then "ISO code &REGION_ISO. is not unique in ATTRLOOKUP. Please specify a different ISO code." 
         else "" 
      end
   into :ERROR_COUNT, :ERROR_MESSAGE
      from valib.attrlookup_original
         where ISO eq "&REGION_ISO.";
quit;

%ErrorTest;

/* Remove any previous entries if required */
proc sql;
   delete from valib.attrlookup where ID like "&REGION_PREFIX.%";
   delete from valib.centlookup where ID like "&REGION_PREFIX.%";
quit;

/* Step 1: Import the SHP file into SAS */
PROC MAPIMPORT DATAFILE="&REGION_SHP_FILE."
   OUT=&REGION_DATASET.;
   ID &REGION_SHP_ID_COL.;
RUN;

/* Add the DENSITY column to the polygon data set used to reduce the polygon density in the visualization */
proc greduce data=&REGION_DATASET. out=&REGION_DATASET.;
   id &REGION_SHP_ID_COL.;
run;

/* Determine the column type of REGION_SHP_ID_COL and REGION_SHP_NAME_COL */
data _null_;
   set &REGION_DATASET.(obs=1);
   call symputx('REGION_SHP_ID_COL_TYPE', vtype(&REGION_SHP_ID_COL.));
   call symputx('REGION_SHP_NAME_COL_TYPE', vtype(&REGION_SHP_NAME_COL.));
run;

%put &=REGION_SHP_ID_COL_TYPE;
%put &=REGION_SHP_NAME_COL_TYPE;

/* Step 2: Region lookup can either be via IDLABEL (IDNAME) or ID. In case we lookup by IDLABEL let's generate a 
unique name. The following steps might need to be adjusted dependent on your source data.

Depending on your source data, you might want to concatenate the &REGION_SHP_NAME column with another column 
in order to ensure that the values are unique.
*/

/*===== Update the following code as needed -- see the comment block above =====*/

%macro createIdFormat();
   proc sql;
      create table work.idname_fmt as
         select distinct
            "idname" as FMTNAME,
            "&REGION_SHP_ID_COL_TYPE." as TYPE,
            &REGION_SHP_ID_COL. as START,
               %if %upcase(&REGION_SHP_NAME_COL_TYPE.) eq N %then %do;
                  /* convert column to character if required */
               compress(put(&REGION_SHP_NAME_COL.,best32.))
               %end;
               %else %do;
               trim(left(&REGION_SHP_NAME_COL.))
               %end;
               as LABEL
   from  &REGION_DATASET.;
quit;
%mend createIdFormat;
%createIdFormat;

/*===== End code updates =====*/

/* [VALIDATION STEP] Check for duplicate names in the IDNAME lookup data set. With duplicate entries here the idname based lookup would not work.
If you have names listed here, revisit the previous step to make sure each LABEL is unique, for example, by merging other parent level details */
proc sql noprint;
   create table work.nonunique_names 
      as select distinct LABEL, count(LABEL) as count
         from work.idname_fmt 
            group by LABEL 
               having calculated count > 1   
                  order by count desc;

   /* count and create error code if greater than zero */
   select count(*) as count,
      case 
         when calculated count > 0 then compress(put(calculated count,8.)) 
         || " duplicate names have been found. Please check the idname_fmt table for duplicates."
         || " A list of duplicate names are in WORK.NONUNIQUE_NAMES."
         else "" 
      end
   into :ERROR_COUNT, :ERROR_MESSAGE
      from work.nonunique_names;
quit;

%ErrorTest;

proc format cntlin=work.idname_fmt;
run;

/* [VALIDATION STEP] Check for required columns in the input polygon data set. */
data _null_;
   dsid = open("&REGION_DATASET.");
   array colNames(5) $50 _temporary_ ("&REGION_SHP_ID_COL.", "X", "Y", "SEGMENT", "DENSITY");

   do i = lbound(colNames) to hbound(colNames);
      check = varnum(dsid, colNames(i));

      if check eq 0 then
         do;
            call symputx('ERROR_COUNT', 1);
            call symputx('ERROR_MESSAGE',"Column " || compress(colNames(i)) || " is required in &REGION_DATASET.");
            stop;
         end;
   end;
run;

%ErrorTest;

/* [VALIDATION STEP] Check for conflicting columns in the input polygon data set. */
data _null_;
   array colNames(7) $50 _temporary_ ("IDNAME", "LONG", "LAT", "RESOLUTION", "LAKE", "ISOALPHA2", "AdminType");

   do i = lbound(colNames) to hbound(colNames);
      if colNames(i) eq "&REGION_SHP_ID_COL." then
         do;
            call symputx('ERROR_COUNT', 1);
            call symputx('ERROR_MESSAGE',"Column name for REGION_SHP_ID_COL conflicts with predefined column " || compress(colNames(i)) || ".");
            stop;
         end;
   end;
run;

%ErrorTest;

/* Step 3: Create the final polygon data set with the required set of columns. We are going to create a new
shorter ID column here as the original ID columns are often long and unnecessarily complex. Note, we also apply 
the previously created idname format to the IDNAME column. 
*/
data &REGION_DATASET.;
   set &REGION_DATASET.(keep=&REGION_SHP_ID_COL. X Y SEGMENT DENSITY);

   /* create new (shorter) ID */
   length _TMP_ $60. _SID_ 8.;

   if (_n_ eq 1) then
      do;
         _SID_ = 1;
         _TMP_ = &REGION_SHP_ID_COL.;
      end;

   if _TMP_ ne &REGION_SHP_ID_COL. then
      _SID_ = _SID_ + 1;
   _TMP_ = &REGION_SHP_ID_COL.;
   retain _TMP_ _SID_;
   drop _TMP_ _SID_;
   _RID_ = compress("&REGION_PREFIX.-" || put(_SID_,8.));
   IDNAME = put(&REGION_SHP_ID_COL., idname.);
   LONG = X;
   LAT = Y;
   ISO = "&REGION_ISO.";
   RESOLUTION = 1;
   LAKE = 0;
   ISOALPHA2 = "&REGION_PREFIX.";
   AdminType = "regions";
   where density<&REGION_SHP_DENSITY.;
   keep _RID_ SEGMENT IDNAME LONG LAT X Y ISO DENSITY RESOLUTION LAKE ISOALPHA2 AdminType;
   rename _RID_=ID;
run;

/* Step 4: Add a custom region (country) to ATTRLOOKUP - a new entry will appear in the VA country selection list */
proc sql;
   insert into valib.attrlookup
      values ( 
         "&REGION_LABEL.",         /* IDLABEL=State/Province Label */
         "&REGION_PREFIX.",        /* ID=SAS Map ID Value */
         "&REGION_LABEL.",         /* IDNAME=State/Province Name */
         "",                       /* ID1NAME=Country Name */
         "",                       /* ID2NAME */
         "&REGION_ISO.",           /* ISO=Country ISO Numeric Code */
         "&REGION_LABEL.",         /* ISONAME */
         "&REGION_LABEL.",         /* KEY */
         "",                       /* ID1=Country ISO 2-Letter Code */
         "",                       /* ID2 */
         "",                       /* ID3 */
         "",                       /* ID3NAME */
         0                         /* LEVEL (0=country level, 1=state level) */
         );
quit;

/* Register each single region in the lookup data set */
proc sql;
   insert into valib.attrlookup
      select distinct 
         IDNAME,                             /* IDLABEL=State/Province Label */
         ID,                                 /* ID=SAS Map ID Value */
         IDNAME,                             /* IDNAME=State/Province Name */

         "&REGION_LABEL.",                   /* ID1NAME=Country Name */
         "",                                 /* ID2NAME */
         "&REGION_ISO.",                     /* ISO=Country ISO Numeric Code */
         "&REGION_LABEL.",                   /* ISONAME */
         trim(IDNAME) || "|&REGION_LABEL.",  /* KEY */

         "&REGION_PREFIX.",                  /* ID1=Country ISO 2-Letter Code */
         "",                                 /* ID2 */
         "",                                 /* ID3 */
         "",                                 /* ID3NAME */
         1                                   /* LEVEL (1=state level) */
   from &REGION_DATASET.;
quit;

/* Register custom region in CENTLOOKUP */
proc sql;
   /* Add custom region */
   insert into valib.centlookup
      select distinct
         "&REGION_DATASET." as mapname,
         "&REGION_PREFIX." as ID,
         avg(x) as x,
         avg(y) as y
      from &REGION_DATASET.;

   /* Add custom provinces */
   insert into valib.centlookup
      select distinct
         "&REGION_DATASET." as mapname,
         ID as ID,
         avg(x) as x,
         avg(y) as y
      from &REGION_DATASET.
         group by id;
quit;

/* Step 5: (optional) Creates a validation data set which can be used to validate the newly added regions in SAS Visual Analytics */
proc sql;
   create table &REGION_DATASET._VALIDATE as 
      select distinct ID as ID, 
         IDNAME as NAME 
      from &REGION_DATASET.;
   create table &REGION_DATASET._VALIDATE as 
      select *, 
         round(ranuni(1) * 10000) as measure1, 
         round(ranuni(1) * 100000) as measure2 format=dollar20.0 
      from &REGION_DATASET._VALIDATE
         group by ID, NAME 
            order by ID, NAME;
quit;
diassis
Fluorite | Level 6

Olá Boa Tarde,

 

Não sei bem qual é o seu objetivo, mas o SAS VA já tem polígonos pré-definidos para os estados brasileiros (e de províncias da maioria dos países). Mas se for para criar novos polígonos, como por exemplo criar relacionados a áreas delimitadas (bairros, por exemplo), aí terá que seguir os artigos das demais respostas.

 

O Link do vídeo abaixo, mostra como utilizar o potencial do SAS vA:

(145) Webinar | SAS Visual Analytics 2: Geolocalización - YouTube

 

arthurdpereira
Fluorite | Level 6

Agradeço a todos pela tentativa de me ajudar a solucionar o meu problema, porém, o link que mais me deu entendimento detalhado de como fazer foi esse:
https://blogs.sas.com/content/sgf/2018/01/26/how-to-create-custom-regional-maps-in-sas-visual-analyt...

O código, no final, ficou dessa forma:

/* Fazer o Download do Arquivo GeoJSON do Github */
filename mapa temp;

proc http
	url="https://raw.githubusercontent.com/tbrugz/geodata-br/master/geojson/geojs-32-mun.json"
	method="GET"
	out=mapa;
run;

/* Ler o Arquivo GeoJSON usando a Biblioteca JSON */
libname jsonlib json fileref=mapa;

/* Examinar a Estrutura do GeoJSON */
proc contents data=jsonlib._all_;
run;

/* Unir as tabelas */
data map_data;
    merge jsonlib.features_properties 
          jsonlib.features_geometry (keep=ordinal_features ordinal_geometry type);
    by ordinal_features;
run;

/* Preparar os dados para o gráfico GMAP */
data map_data;
    merge map_data
          jsonlib.geometry_coordinates;
    by ordinal_geometry;
run;

/* Preparar os dados para a Plotagem */
data plot_data (drop=element1 element2);
    set map_data;
    x = element1;
    y = element2;
    i = 1;
    output;
run;

/* Plotar o gráfico */
proc gmap data=plot_data map=plot_data;
    id name;
    choro name / nolegend levels=1;
run;

/*A partir daqui, são passos para disponibilizar a tabela no CAS e consequentemente disponibilizar no VA*/
%macro sas_load_data_cas(incaslib=,casdata=,data=,outcaslib=, casout=);
/*Deleta tabela "in-memory"*/
proc casutil;
droptable incaslib = "&outcaslib." casdata = "&casdata." quiet;
run;

/*Carrega tabela no  CAS*/
proc casutil;
  load data=&data. casout="&casout." outcaslib=&outcaslib. replace;
quit;

/* Promove a tabela para uma "global session" (disponivel para todos os usuário acesso ao servidor) */
proc casutil;
promote incaslib = "&outcaslib." casdata = "&casdata."
outcaslib = "&outcaslib." casout = "&casout.";
quit;
%mend sas_load_data_cas;
%sas_load_data_cas(incaslib=Public,casdata=PLOT_MAPA,data=WORK.PLOT_DATA,outcaslib=Public, casout=PLOT_MAPA)

Depois daqui, basta seguir os passos do link a partir do Step 8, sendo o i=segmento.