{"id":135,"date":"2007-05-18T18:18:37","date_gmt":"2007-05-18T22:18:37","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/2007\/05\/18\/upslope-area-part-3\/"},"modified":"2019-10-23T12:55:18","modified_gmt":"2019-10-23T16:55:18","slug":"upslope-area-part-3","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2007\/05\/18\/upslope-area-part-3\/","title":{"rendered":"Upslope area &#8211; Flow examples"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <p>In <a href=\"https:\/\/blogs.mathworks.com\/steve\/2007\/04\/26\/upslope-area-part-2\/\">Part 2<\/a> of the upslope area series, I showed an M-file, <tt>pixelFlow<\/tt>, that could calculate a pixel's flow direction and magnitude according to the D-infinity method of Tarboton.\r\n   <\/p>\r\n   <p>Let's try the function with a simple test case first, and then we'll try it with some DEM data.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">Z = peaks;\r\nmesh(peaks)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2007\/May\/upslope_part3_01.png\"> <p><tt>pixelFlow<\/tt> works on a single pixel at a time, so we put it into a loop to calculate the flow direction, <tt>r<\/tt>, and the flow magnitude, <tt>s<\/tt>, for all the interior elements of <tt>Z<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[M,N] = size(Z);\r\nr = zeros(M-2, N-2);\r\ns = zeros(M-2, N-2);\r\n<span style=\"color: #0000FF\">for<\/span> i = 1:M-2\r\n    <span style=\"color: #0000FF\">for<\/span> j = 1:N-2\r\n        [r(i,j), s(i,j)] = pixelFlow(Z,i+1,j+1);\r\n    <span style=\"color: #0000FF\">end<\/span>\r\n<span style=\"color: #0000FF\">end<\/span><\/pre><p>Now display the peaks matrix as a grayscale image and superimpose a quiver plot.<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">imshow(peaks,[],<span style=\"color: #A020F0\">'initialmag'<\/span>,<span style=\"color: #A020F0\">'fit'<\/span>)\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\n[x,y] = meshgrid(2:N-1,2:M-1);\r\nquiver(x, y, s.*cos(r), -s.*sin(r), 2, <span style=\"color: #A020F0\">'y'<\/span>)\r\naxis <span style=\"color: #A020F0\">equal<\/span>\r\nhold <span style=\"color: #A020F0\">off<\/span><\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2007\/May\/upslope_part3_02.png\"> <p>Zoom in on a low point:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">xlim([20 35]);\r\nylim([5 20])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2007\/May\/upslope_part3_03.png\"> <p>And a high point:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">xlim([30 40])\r\nylim([15 30])<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2007\/May\/upslope_part3_04.png\"> <p>To get a real digital elevation model (DEM) to play with, I started at a page that the Mapping Toolbox development team fondly\r\n      calls Tech Support Note 2101: <a title=\"https:\/\/www.mathworks.com\/support\/tech-notes\/2100\/2101.html (link no longer works)\">\"Accessing Geospatial Data on the Internet for the Mapping Toolbox.\"<\/a> That page directed me to GeoCommunity, one of the distribution points for free DEM data from the <a href=\"http:\/\/www.usgs.gov\">United States Geological Survey (USGS)<\/a>.  Downloading\r\n      DEM data set 1643091 and using the Mapping Toolbox function <tt>sdtsdemread<\/tt> gave me this data set:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">s = load(<span style=\"color: #A020F0\">'upslope_sample_dem'<\/span>);\r\nimshow(s.Zm, [], <span style=\"color: #A020F0\">'initialmag'<\/span>, <span style=\"color: #A020F0\">'fit'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2007\/May\/upslope_part3_05.png\"> <p>Near the center of this data set is <a href=\"http:\/\/maps.google.com\/maps?ie=UTF8&amp;hl=en&amp;ll=42.190309,-71.550608&amp;spn=0.044197,0.066605&amp;t=h&amp;z=14&amp;om=1\">North Pond<\/a>, close to where I live and about 3 miles southwest of the Boston Marathon starting line.  (The high spot west of the pond\r\n      is Peppercorn Hill, a great place for a Cub Scout hike.)\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">pond = s.Zm(140:280, 160:230);\r\nimshow(pond, [], <span style=\"color: #A020F0\">'initialmag'<\/span>, <span style=\"color: #A020F0\">'fit'<\/span>)\r\ntitle(<span style=\"color: #A020F0\">'North Pond'<\/span>)<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2007\/May\/upslope_part3_06.png\"> <p>Let's try <tt>pixelFlow<\/tt> on this data set.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">[M,N] = size(pond);\r\nr = zeros(M-2, N-2);\r\ns = zeros(M-2, N-2);\r\n<span style=\"color: #0000FF\">for<\/span> i = 1:M-2\r\n    <span style=\"color: #0000FF\">for<\/span> j = 1:N-2\r\n        [r(i,j), s(i,j)] = pixelFlow(pond,i+1,j+1);\r\n    <span style=\"color: #0000FF\">end<\/span>\r\n<span style=\"color: #0000FF\">end<\/span>\r\n\r\nimshow(pond,[],<span style=\"color: #A020F0\">'initialmag'<\/span>,<span style=\"color: #A020F0\">'fit'<\/span>)\r\nhold <span style=\"color: #A020F0\">on<\/span>\r\n[x,y] = meshgrid(2:N-1,2:M-1);\r\nquiver(x, y, s.*cos(r), -s.*sin(r), 2, <span style=\"color: #A020F0\">'y'<\/span>)\r\naxis <span style=\"color: #A020F0\">equal<\/span>\r\n\r\n<span style=\"color: #228B22\">% Zoom in on the southern end of the pond.<\/span>\r\nxlim([15 60])\r\nylim([75 105])\r\n\r\nhold <span style=\"color: #A020F0\">off<\/span><\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2007\/May\/upslope_part3_07.png\"> <p>That seems to be working pretty well, but there's an unresolved problem to explore - what to do about plateaus.  Recall the\r\n      last few lines of <tt>pixelFlow<\/tt>:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">dbtype <span style=\"color: #A020F0\">pixelFlow<\/span> <span style=\"color: #A020F0\">47:51<\/span><\/pre><pre style=\"font-style:oblique\">\r\n47    else\r\n48        % The pixel is in a flat area or is a pit.  Flow direction angle is\r\n49        % unresolved.\r\n50        r = NaN;\r\n51    end\r\n\r\n<\/pre><p>For example:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">Zp = repmat([1:3 3 3 3:6],5,1)<\/pre><pre style=\"font-style:oblique\">\r\nZp =\r\n\r\n     1     2     3     3     3     3     4     5     6\r\n     1     2     3     3     3     3     4     5     6\r\n     1     2     3     3     3     3     4     5     6\r\n     1     2     3     3     3     3     4     5     6\r\n     1     2     3     3     3     3     4     5     6\r\n\r\n<\/pre><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">r = zeros(size(Zp)-2);\r\n<span style=\"color: #0000FF\">for<\/span> i = 1:size(r,1)\r\n    <span style=\"color: #0000FF\">for<\/span> j = 1:size(r,2)\r\n        r(i,j) = pixelFlow(Zp, i+1, j+1);\r\n    <span style=\"color: #0000FF\">end<\/span>\r\n<span style=\"color: #0000FF\">end<\/span>\r\n\r\nr<\/pre><pre style=\"font-style:oblique\">\r\nr =\r\n\r\n    3.1416    3.1416       NaN       NaN       NaN    3.1416    3.1416\r\n    3.1416    3.1416       NaN       NaN       NaN    3.1416    3.1416\r\n    3.1416    3.1416       NaN       NaN       NaN    3.1416    3.1416\r\n\r\n<\/pre><p>The pixel flow direction is to the left (<tt>r<\/tt> = pi) except for the middle pixels, for which <tt>pixelFlow<\/tt> could not compute a direction.\r\n   <\/p>\r\n   <p>I'll pursue the issue of plateaus next week.<\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_bbae4938451544759fa8339dcc31c46a() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='bbae4938451544759fa8339dcc31c46a ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' bbae4938451544759fa8339dcc31c46a';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        author = 'Steve Eddins';\r\n        copyright = 'Copyright 2007 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n      \r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }   \r\n      \r\n-->\r\n<\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_bbae4938451544759fa8339dcc31c46a()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.4<br><\/p>\r\n<\/div>\r\n<!--\r\nbbae4938451544759fa8339dcc31c46a ##### SOURCE BEGIN #####\r\n%%\r\n% In <https:\/\/blogs.mathworks.com\/steve\/2007\/04\/26\/upslope-area-part-2\/ Part 2>\r\n% of the upslope area series, I showed an M-file, |pixelFlow|, that\r\n% could calculate a pixel's flow direction and magnitude according to the\r\n% D-infinity method of Tarboton.\r\n%\r\n% Let's try the function with a simple test case first, and then we'll try\r\n% it with some DEM data.\r\n\r\nZ = peaks;\r\nmesh(peaks)\r\n\r\n%%\r\n% |pixelFlow| works on a single pixel at a time, so we put it into a loop\r\n% to calculate the flow direction, |r|, and the flow magnitude, |s|, for\r\n% all the interior elements of |Z|.\r\n\r\n[M,N] = size(Z);\r\nr = zeros(M-2, N-2);\r\ns = zeros(M-2, N-2);\r\nfor i = 1:M-2\r\n    for j = 1:N-2\r\n        [r(i,j), s(i,j)] = pixelFlow(Z,i+1,j+1);\r\n    end\r\nend\r\n\r\n%%\r\n% Now display the peaks matrix as a grayscale image and superimpose a\r\n% quiver plot.\r\n\r\nimshow(peaks,[],'initialmag','fit')\r\nhold on\r\n[x,y] = meshgrid(2:N-1,2:M-1);\r\nquiver(x, y, s.*cos(r), -s.*sin(r), 2, 'y')\r\naxis equal\r\nhold off\r\n\r\n%%\r\n% Zoom in on a low point:\r\n\r\nxlim([20 35]);\r\nylim([5 20])\r\n\r\n%%\r\n% And a high point:\r\n\r\nxlim([30 40])\r\nylim([15 30])\r\n\r\n%%\r\n% To get a real digital elevation model (DEM) to play with, I started at a\r\n% page that the Mapping Toolbox development team fondly calls Tech Support\r\n% Note 2101: <https:\/\/www.mathworks.com\/support\/tech-notes\/2100\/2101.html \r\n% \"Accessing Geospatial Data on the Internet for the Mapping Toolbox.\">\r\n% That page directed me to <www.geocomm.com GeoCommunity>, one of the\r\n% distribution points for free DEM data from the [www.usgs.gov United \r\n% States Geological Survey (USGS).  Downloading DEM data set 1643091 and\r\n% using the Mapping Toolbox function |sdtsdemread| gave me this data set:\r\n\r\ns = load('upslope_sample_dem');\r\nimshow(s.Zm, [], 'initialmag', 'fit')\r\n\r\n%%\r\n% Near the center of this data set is \r\n% <http:\/\/maps.google.com\/maps?ie=UTF8&hl=en&ll=42.190309,-71.550608&spn=0.044197,0.066605&t=h&z=14&om=1 \r\n% North Pond>, close to where I live and\r\n% about 3 miles southwest of the Boston Marathon starting line.  (The high\r\n% spot west of the pond is Peppercorn Hill, a great place for a Cub Scout\r\n% hike.)\r\n\r\npond = s.Zm(140:280, 160:230);\r\nimshow(pond, [], 'initialmag', 'fit')\r\ntitle('North Pond')\r\n\r\n%%\r\n% Let's try |pixelFlow| on this data set.\r\n\r\n[M,N] = size(pond);\r\nr = zeros(M-2, N-2);\r\ns = zeros(M-2, N-2);\r\nfor i = 1:M-2\r\n    for j = 1:N-2\r\n        [r(i,j), s(i,j)] = pixelFlow(pond,i+1,j+1);\r\n    end\r\nend\r\n\r\nimshow(pond,[],'initialmag','fit')\r\nhold on\r\n[x,y] = meshgrid(2:N-1,2:M-1);\r\nquiver(x, y, s.*cos(r), -s.*sin(r), 2, 'y')\r\naxis equal\r\n\r\n% Zoom in on the southern end of the pond.\r\nxlim([15 60])\r\nylim([75 105])\r\n\r\nhold off\r\n\r\n%%\r\n% That seems to be working pretty well, but there's an unresolved problem\r\n% to explore - what to do about plateaus.  Recall the last few lines of \r\n% |pixelFlow|:\r\n\r\ndbtype pixelFlow 47:51\r\n\r\n%%\r\n% For example:\r\n\r\nZp = repmat([1:3 3 3 3:6],5,1)\r\n\r\n%%\r\nr = zeros(size(Zp)-2);\r\nfor i = 1:size(r,1)\r\n    for j = 1:size(r,2)\r\n        r(i,j) = pixelFlow(Zp, i+1, j+1);\r\n    end\r\nend\r\n\r\nr\r\n\r\n%%\r\n% The pixel flow direction is to the left (|r| = pi) except for the middle\r\n% pixels, for which |pixelFlow| could not compute a direction.\r\n%\r\n% I'll pursue the issue of plateaus next week.\r\n% \r\n##### SOURCE END ##### bbae4938451544759fa8339dcc31c46a\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   In Part 2 of the upslope area series, I showed an M-file, pixelFlow, that could calculate a pixel's flow direction and magnitude according to the D-infinity method of Tarboton.\r\n   \r\n   Let's... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2007\/05\/18\/upslope-area-part-3\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[9],"tags":[50,90,36,362,356,30,354,358,190,52,360,298,130],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/135"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=135"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/135\/revisions"}],"predecessor-version":[{"id":2246,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/135\/revisions\/2246"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=135"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=135"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=135"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}