*
;

options nosource;
/*
 A - CALCULATES AREAS AND MAIN POINTS FROM MAP DATA SETS,
     IN UNITS OF LONGITUDE/LATITUDE COORDINATES

    Written:  July 19, 1993
    Developed using SAS 6.07 on VM/CMS and SAS 6.04 on DOS PC
    Author: Arnold Schick
    Procs:   -
    Other:  SAS MACRO language
    Macros: only A
    Note:   Do not use _AREA_ as a data set name, this data set
            contains the results and is new created by every run.
            Please be sure, some map datasets use ID instead of
            SEGMENT and vice versa, or STATE as ID.


    Macro Call: %A(DATA,X,Y,ID,SEGMENT,XSCALE,YSCALE);


MACRO VARIABLE      DESCRIPTION
------------------+-------------------------------------------------
 In Request:

 DATA               Name of SAS data set with input data. If this
                    parameter is missing or blank _LAST_ is used.


 X                  Variblename of latitude in input SAS MAP data
                    data set. If missing or blank, X is used.

 Y                  Variablename of longitude in input SAS MAP data
                    If missing or blank, Y is used.

 ID                 Variablname of id SAS MAP data set variable.
                    If missing or blank, ID is used.

 SEGMENT            Variablename of segment SAS MAP data set variable.
                    If blank or missing, SEGMENT is used. If not
                    in input data set, SEGMENT is set to missing.

 XSCALE             Value of scaling-factor for latitude-values.
                    If missing or blank, 1.0 is used. XSCALE <> 0 !

 YSCALE             Value of scaling-factor for longitude-values.
                    If missing or blank, 1.0 is used. YSCALE <> 0 !

Examples:

*%macro A (data,        x,y,id,segment,1,1);
       %A (maps.us ,    x,y,state,segment,1,1);
       %A (maps.germany);


Reference:

For more information:

 Arnold Schick

 University of Marburg
 Academic Computing Center
 Hans-Meerwein-Str.
 3550 Marburg/Lahn   Germany

 Internet: schick@hrz.uni-marburg.de

 If you  find an error-condition (it is provided 'as it is')
 please let me know about this error-condition. And when you
 have good tips for better formulation with SAS, let me also know.

 Please acknowledge the author as the provider of this method
 in publications that it used. Thank you very much.
  */


%macro A (data,x,y,id,segment,xscale,yscale);
options nosource nostimer nosymbolgen nonotes;

  %if &data    =  or &data    = . %then %let data   = _LAST_ ;
  %if &x       =  or &x       = . %then %let x      = x;
  %if &y       =  or &y       = . %then %let y      = y;
  %if &id      =  or &id      = . %then %let id     = id;
  %if &segment =  or &segment = . %then %let segment = segment;
  %if %str(&xscale) = %str(0) or
      %str(&yscale) = %str(0) %then %goto quit_1;

  data _NULL_;
    xs = symget('xscale') / 1 ;
    if xs = . then xs = 1;  call symput('xscale',xs);
    ys = symget('yscale') / 1 ;
    if ys = . then ys = 1;  call symput('yscale',ys);
  run;

  data _area_ (rename=(id_previ=&id seg_prev=&segment)
                 keep=id_previ id_face seg_prev seg_face ax ay)
       a (keep= ax ay adx ady);
    set &data end=last;
    retain id_face 0 face 0 seg_face 0 y_sourc2 isle 1 adx 0 ady 0 ax 0 ay 0;
    &x = &x*&xscale;
    &y = &y*&yscale;
    x_previo = lag(&x);
    y_previo = lag(&y);
    id_previ = lag(&id);
    seg_prev = lag(&segment);
    xm=(&x-x_previo)/2 + x_previo;
    if &x = .  then do;
      seg_face + isle*abs(face);
      ax + isle*abs(adx);
      ay + isle*abs(ady);
      y_sourc2 = 0;
      face     = 0;
      isle     = -1;
      adx = 0;
      ady = 0;
    end;
    else y_sourc2 = (xm-x_previo)*y_previo + (&x-xm)*&y;
    if ((id_previ ^= &id) or (&segment ^= seg_prev)) and
         _N_ > 1 then do;
           seg_face + isle*abs(face);
           seg_face = abs(seg_face);
           id_face + seg_face;
           ax + isle*abs(adx); ay + isle*abs(ady);
           output a;
           ax = ax/id_face;
           ay = ay/id_face;
           output a;
           output _area_;
           if &id ^= id_previ then id_face = 0;
           isle = 1;
           face = 0;
           seg_face  = 0;
           adx = 0;  ax = 0;
           ady = 0;  ay = 0;
        end;
      else if &x ^= . then
             if &x > x_previo
                then do;
                     face + -abs(y_sourc2);
                     adx + -abs(y_sourc2)*xm;
                     ady + -abs(y_sourc2)*y_sourc2/(2*(&x-x_previo));
                   *  output a;
                 end;
                else if &x=x_previo then do; * output a; end;
                         else do;
                              face + abs(y_sourc2);
                              adx + abs(y_sourc2)*xm;
                              ady + abs(y_sourc2)*y_sourc2/(2*(&x-x_previo));
                            *  output a;
                          end;
    if last then do;
       seg_face + isle*abs(face);
       seg_face = abs(seg_face);
       id_face + seg_face;
       ax + isle*abs(adx);
       ay + isle*abs(ady);
       output a;
       ax = ax/id_face;  ay = ay/id_face;
       output a;
       output _area_;
    end;
  run;

options notes;
data  _area_;
  set _area_;
run;
options nonotes;

%goto final;
%quit_1 : %put          MACRO-HALT: Scaling-factor(s) equal 0 ;
%final : ;
options source stimer notes;
%mend A; options source;


*Example;

/*
*libname in 'c:\d\sas\maps';
data one;
  set in.brdlan;
  *where id in (1 6 8 11); *selects wanted regions;
run;


%a(one,x,y,id,segment);

proc sort data=_area_ out=_area_;
  by id segment;
run;
data _area_ ;
  set _area_ ;
  keep id id_face seg_face ax ay;
  if last.id or last.segment then output;
  by id segment;
run;
proc print data=_area_;
run;

*calculates mainpoint of all areas;

data sum (keep=summa px py);
  set _area_ end=last;
  summa + id_face;
  px + id_face * ax;
  py + id_face * ay;
  if last then do;
    px=px/summa;
    py=py/summa;
    output;
end;
run;
proc print data=sum;
run;

*End of Example;

*/


*
;