Code covered by the BSD License  

Highlights from
Google Earth Toolbox

image thumbnail
from Google Earth Toolbox by scott lee davis
Various plotting/drawing functions that can be saved as KML output, and loaded in Google Earth

ge_contourf(x,y,z,varargin)
function varargout = ge_contourf(x,y,z,varargin)
% Reference page in help browser:
%
% <a href="matlab:web(fullfile(ge_root,'html','ge_contourf.html'),'-helpbrowser')">link</a> to html documentation
% <a href="matlab:web(fullfile(ge_root,'html','license.html'),'-helpbrowser')">show license statement</a>
%


AuthorizedOptions = authoptions( mfilename );


id = 'contourf';
idTag = 'id';
name = 'ge_contourf';
timeStamp = ' ';
timeSpanStart = ' ';
timeSpanStop = ' ';
description = '';
visibility = 1;
lineColor = '00000000';
lineColorPolyMax = '00000000';
lineWidth = 0.25;
snippet = ' ';
extrude = 0;
tessellate = 1;
altitudeMode = 'clampToGround';
msgToScreen = false;
region   = ' ';
cMap = 'jet';
nearInf = abs(max(z(:))*10);
%       cLimHigh = max(max(z(2:end-1,2:end-1)));
%        cLimLow = min(min(z(2:end-1,2:end-1)));
altitude = 1.0;
polyAlpha = 'C0';
autoClose = true;
tinyRes = 1e-4;
lineValues = [];
numClasses = [];
numClassesDefault = 15;
cLimHigh = max(z(:));
cLimLow = min(z(:));

parsepairs %script that parses Parameter/value pairs.

minz = min(z(:));
maxz = max(z(:));


if isempty(numClasses)&~isempty(lineValues)
    if cLimHigh<maxz
        lineValues = unique([lineValues,maxz,nearInf]);
    else
        lineValues = unique([lineValues,nearInf]);
    end
elseif ~isempty(numClasses)&isempty(lineValues)
    if cLimHigh<maxz
        TMP = linspace(cLimLow,cLimHigh,numClasses+1);
        lineValues = [TMP(1:end),maxz,nearInf];
    else
        lineValues = [linspace(cLimLow,cLimHigh,numClasses+1),nearInf];
    end
elseif isempty(numClasses)&isempty(lineValues)
    % do nothing
    numClasses = 10;
    lineValues = [linspace(cLimLow,cLimHigh,numClasses+1),nearInf];
else
    error('Cannot have both lineValues and numClasses')
end



% if cLimHigh<maxz
%     lineValues = [linspace(cLimLow,cLimHigh,numClasses+1),maxz,nearInf];
% else
%     lineValues = [linspace(cLimLow,cLimHigh,numClasses+1),nearInf];
% end


[nR,nC] = size(z);
tmp_z = ones([nR,nC]+2)*nearInf;
tmp_z(2:end-1,2:end-1) = z;
z = tmp_z;

if msgToScreen
    disp(['Running ' mfilename '...'])
end

if lineWidth==0
    lineColor='00000000';
end

if( isempty( x ) || isempty( y ) || isempty(z) )
    error('empty coordinates passed to ge_contour().');
end


if ~(isequal(altitudeMode,'clampToGround')||...
        isequal(altitudeMode,'relativeToGround')||...
        isequal(altitudeMode,'absolute'))

    error(['Variable ',39,'altitudeMode',39, ' should be one of ' ,39,'clampToGround',39,', ',10,39,'relativeToGround',39,', or ',39,'absolute',39,'.' ])

end

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %


if ndims(x)==2 && all(size(x)>1)
    xv = x(1,:);
else
    xv = x;
end

if ndims(y)==2 && all(size(y)>1)
    yv = y(:,1);
else
    yv = y;
end

dx = ((xv(end)-xv(1))/(numel(xv)-1))*tinyRes;
xv = [xv(1)-dx,xv,xv(end)+dx];
dy = ((yv(end)-yv(1))/(numel(yv)-1))*tinyRes;
yv = [yv(1)-dy;yv;yv(end)+dy];

contourArray = contourc(xv,yv,z,lineValues);


%save contourcresult.mat contourArray

if ischar(cMap)

    figHandles = get(0,'children');

    while true
        RIx = round(rand*1e9);
        if ~ismember(RIx,figHandles)
            figure(RIx)
            eval(['C1 = colormap(' cMap '(256));']);
            break
        end
    end
    close(RIx)
    clear RIx

else
    C1 = cMap;
end

X = linspace(0,1,size(C1,1))';
YRed = C1(:,1);
YGreen = C1(:,2);
YBlue = C1(:,3);



polyClosedThreshold = 1e-5; % Declare polygons closed when their start...
% and end points are separated by a distance...
% less than this value.

contourCell = parsecontarray(contourArray,nearInf);
% lineValuesMinMax = min(z(:));
%
% for k=1:size(contourCell,1)
%     lineValuesMinMax = [lineValuesMinMax;contourCell{k,1}];
% end
% lineValuesMinMax = unique([lineValuesMinMax(:);max(z(:))]);



% colorLevelInc = 0;
nRecords = size(contourCell,1);
isInnerArray=repmat(NaN,[nRecords,1]);
% aa=[]
kmlStr = '';
for m = 1:nRecords % my

    isInnerArray(:) = NaN;

    for o = [1:m-1,m+1:nRecords]

        % isinner(myRecord,otherRecord)
        isInnerArray(o,1)=isinner(contourCell(m,1:4),contourCell(o,1:4),lineValues);

    end

    if isclosed(contourCell(m,:),polyClosedThreshold)

        if hasouter(contourCell,m)
            colorLevelInc = 0;
        else
            colorLevelInc = 0;
        end

        levelDiff = abs(contourCell{m,1}-lineValues);
        colorLevel = find(levelDiff==min(levelDiff));
        colorDist = (cLimHigh-cLimLow);        
        if colorLevel==1|colorLevel==numel(lineValues)-1
            f = (mean(lineValues(colorLevel+colorLevelInc+[0]))-cLimLow)/colorDist;
%         elseif colorLevel==numel(lineValues)-1
%             f = (mean(lineValues(colorLevel+colorLevelInc+[1]))-cLimLow)/colorDist
        else
            f = (mean(lineValues(colorLevel+colorLevelInc+[0,1]))-cLimLow)/colorDist;
        end %colorLevel==1

        if f<0
            f=0;
        end
        if f>1
            f=1;
        end

        YIRed = interp1(X,YRed,f);
        YIGreen = interp1(X,YGreen,f);
        YIBlue = interp1(X,YBlue,f);
        polyColor = [polyAlpha,conv2colorstr(YIRed,YIGreen,YIBlue)];
        %             polyColorCell{colorLevel+colorLevelInc,1} = polyColor;
        innerBoundsStr = buildinnerstr(contourCell,isInnerArray,altitude);

        if colorLevel+colorLevelInc==1
            colorClassStr = sprintf('less than %f',lineValues(colorLevel));
            actualLineColor = lineColor;
%         elseif colorLevel+colorLevelInc>=numel(lineValues)-2
%             colorClassStr = sprintf('more than %f',lineValues(colorLevel-1));
%             actualLineColor = lineColorPolyMax;            
%             %actualLineColor = lineColor;
         else
            colorClassStr = sprintf('%f-%f',lineValues(colorLevel+colorLevelInc-1),lineValues(colorLevel+colorLevelInc));
            actualLineColor = lineColor;
         end

        kmlStr=[kmlStr,ge_poly(contourCell{m,3},contourCell{m,4},...
            'altitude',altitude,...
            'innerBoundsStr',innerBoundsStr,...
            'lineColor',actualLineColor,...
            'lineWidth',lineWidth,...
            'polyColor',polyColor,...
            'autoClose',autoClose,...
            'region', region, ...
            'timeSpanStart',timeSpanStart,...
            'timeSpanStop',timeSpanStop,...
            'altitudeMode',altitudeMode,...
            'tessellate',tessellate,...
            'extrude',extrude,...
            'visibility',visibility,...
            'name',colorClassStr)];
    else
        warning(['Contour line record in ',39,'contourCell{',...
            num2str(m),',1}',39,' skipped',10,...
            'because it is not closed.'])
    end
    %     end
end

% save contourcell.mat contourCell
% figure
% for k=1:size(contourCell,1)
%     plot(contourCell{k,3},contourCell{k,4},'-k.')
%     hold on
% end
%

if nargout==1
    varargout{1} = kmlStr;
elseif nargout==2
    varargout{1} = kmlStr;
    varargout{2} = polyColorCell;
else
end

% aa


% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % %      LOCAL FUNCTIONS START HERE       % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %



function A = parsecontarray(C,nearInf)

% column 1: level
% column 2: number of points
% column 3: xcoords
% column 4: ycoords

curCol = 1;
n = 1;

while curCol<size(C,2)

    L = C(2,curCol);
    lineValue = C(1,curCol);
    if lineValue~=nearInf
        A{n,1} = C(1,curCol);
        A{n,2} = L;
        A{n,3} = C(1,curCol+1:curCol+L);
        A{n,4} = C(2,curCol+1:curCol+L);
        %lineValuesTmp(n,1) = C(1,curCol);
        n = n + 1;
    end

    curCol = curCol + L + 1;

end

%lineValues = unique(lineValuesTmp);


% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
function IO = isclosed(myRecord,thresholdDiff)

L = myRecord{1,2};
xDiff = [myRecord{1,3}(1),myRecord{1,4}(1)];
yDiff = [myRecord{1,3}(L),myRecord{1,4}(L)];

IO = all(abs(xDiff-yDiff)<thresholdDiff);

function IO = isinner(myRecord,otherRecord,lineValues)

% It seems that contourc sometimes rounds off in a weird way...therefore
% a tweak is necessary here, in order not to end up with empty 'myIndexVec'
% and 'otherIndexVec' variables.
% check whether adjacent levels are concerned:
% myIndexVec = find(lineValues==myRecord{1,1});
% otherIndexVec = find(lineValues==otherRecord{1,1});
TMP = unique(lineValues);
dTMP = TMP(2:end)-TMP(1:end-1);
smallestDist = min(unique(dTMP));
roundOffFactor = 100;

myRecordRound = round(myRecord{1,1}/(smallestDist/roundOffFactor))*...
    (smallestDist/roundOffFactor);
otherRecordRound = round(otherRecord{1,1}/(smallestDist/roundOffFactor))*...
    (smallestDist/roundOffFactor);

lineValuesRound = round(lineValues/(smallestDist/roundOffFactor))*...
    (smallestDist/roundOffFactor);

myIndexVec = find(lineValuesRound==myRecordRound);
otherIndexVec = find(lineValuesRound==otherRecordRound);


% firstTest = any(abs(myIndexVec-otherIndexVec)==[1,0]);
firstTest = ismember(myIndexVec-otherIndexVec,[-1,0,1]);

% check whether the points of otherRecord fall within those of myRecord.

if ~firstTest
    IO = false;
else
    IN = inpolygon(otherRecord{1,3},otherRecord{1,4},...
        myRecord{1,3},myRecord{1,4});
    secondTest = all(IN);
end

IO = firstTest && secondTest;


% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %


function innerBoundsStr=buildinnerstr(contourCell,isInnerArray,altitude)
innerBoundsStr='';
oIndex = find(isInnerArray==1)';

% clf
% for u=oIndex
%     plot(contourCell{u,3},contourCell{u,4},'-b')
%     hold on
%     axis image
% end

% initialize 'contained' array:
contained=~(triu(ones(numel(oIndex))).*tril(ones(numel(oIndex))));
if isempty(oIndex)
    iVec = [];
elseif numel(oIndex)==1
    iVec = oIndex(1);
else
    for i = 1:numel(oIndex)
        for j = [1:i-1,i+1:numel(oIndex)]

            u = oIndex(i);
            v = oIndex(j);
            if all(inpolygon(contourCell{u,3},contourCell{u,4},...
                    contourCell{v,3},contourCell{v,4}))
                contained(i,j) = 0;
            end
        end
    end
    iVec = oIndex(sum(contained,2)==numel(oIndex)-1);
end

for elem = iVec
    innerBoundsStr = [innerBoundsStr,...
        '<innerBoundaryIs>',char(10),...
        '   <LinearRing>',char(10),...
        '      <coordinates>',char(10),...
        sprintf('          %.16g,%.16g,%.16g \n',[contourCell{elem,3}',contourCell{elem,4}',...
        altitude*ones(size(contourCell{elem,4}'))]'),char(10),...
        '      </coordinates>',char(10),...
        '   </LinearRing>',char(10),...
        '</innerBoundaryIs>',char(10)];
end

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %


function S = conv2colorstr(B,G,R)
% Please note that this conv2colorstr is different from that in
% ge_colorbar. This one writes KML formatted hexadecimal
% colorstrings, ge_colorbar() writes HTML formatted colorstr.


S='000000';

hexB = dec2hex(round(B*255));
hexG = dec2hex(round(G*255));
hexR = dec2hex(round(R*255));

LB = length(hexB);
LG = length(hexG);
LR = length(hexR);

S(3-LB:2)=hexB;
S(5-LG:4)=hexG;
S(7-LR:6)=hexR;


function IO=hasouter(contourCell,myIndex)

nRecords = size(contourCell,1);

inVec=repmat(NaN,[nRecords,1]);
uVec=[1:myIndex-1,myIndex+1:nRecords];
for u=uVec
    if contourCell{u,1}==contourCell{myIndex,1}
        inVec(u) = all(inpolygon(contourCell{myIndex,3},contourCell{myIndex,4},...
            contourCell{u,3},contourCell{u,4}));
    else
        inVec(u) = false;
    end
end

IO=any(inVec(uVec));





Contact us at files@mathworks.com