<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ibrahim Awad</title>
    <description>The latest articles on DEV Community by Ibrahim Awad (@ibrahimawadhamid).</description>
    <link>https://dev.to/ibrahimawadhamid</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F373563%2F89a67535-fda3-4920-8a86-89611334b2c8.jpeg</url>
      <title>DEV Community: Ibrahim Awad</title>
      <link>https://dev.to/ibrahimawadhamid</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ibrahimawadhamid"/>
    <language>en</language>
    <item>
      <title>Large GeoTiff (raster) files on GeoServer using COG</title>
      <dc:creator>Ibrahim Awad</dc:creator>
      <pubDate>Sat, 04 Sep 2021 19:17:30 +0000</pubDate>
      <link>https://dev.to/ibrahimawadhamid/large-geotiff-raster-files-on-geoserver-using-cog-546h</link>
      <guid>https://dev.to/ibrahimawadhamid/large-geotiff-raster-files-on-geoserver-using-cog-546h</guid>
      <description>&lt;h3&gt;
  
  
  Publish large geotiff (raster) files on GeoServer and be able to access them in no time with COG (Cloud Optimized Geotiff)
&lt;/h3&gt;

&lt;p&gt;The challenge here is that you might have a really large geotiff file (or a normal one). Publishing that file on geoserver would require any client to download the whole file before rendering it (not a good thing if you have a 500MB geotiff!).&lt;/p&gt;

&lt;p&gt;The solution is fairly simple with &lt;strong&gt;COG&lt;/strong&gt; (Cloud Optimized Geotiff). You can check all about COG on the &lt;a href="https://www.cogeo.org/" rel="noopener noreferrer"&gt;official website&lt;/a&gt;, or you can simply read their explanation of COG as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Cloud Optimized GeoTIFF (COG) is a regular GeoTIFF file, aimed at being hosted on a HTTP file server, with an internal organization that enables more efficient workflows on the cloud. It does this by leveraging the ability of clients issuing ​HTTP GET range requests to ask for just the parts of a file they need.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's do it through these steps together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download and use COG validation script.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to &lt;a href="https://github.com/rouault/" rel="noopener noreferrer"&gt;rouault&lt;/a&gt; for creating this awesome &lt;a href="https://github.com/rouault/cog_validator/blob/master/validate_cloud_optimized_geotiff.py" rel="noopener noreferrer"&gt;script&lt;/a&gt;. Save it to your local machine, we will use it in a second.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get your large (or normal) geotiff file in the same directory as the validation &lt;a href="https://github.com/rouault/cog_validator/blob/master/validate_cloud_optimized_geotiff.py" rel="noopener noreferrer"&gt;script&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the sake of this demo, I will use this &lt;a href="http://leoworks.terrasigna.com/files/Envisat_ASAR_2003-08-04.tif" rel="noopener noreferrer"&gt;geotiff&lt;/a&gt;, download it, rename it to &lt;code&gt;envisat.tif&lt;/code&gt; and save it next to the validation &lt;a href="https://github.com/rouault/cog_validator/blob/master/validate_cloud_optimized_geotiff.py" rel="noopener noreferrer"&gt;script&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate the file that it is a geotiff, but not yet a COG.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

python validate_cloud_optimized_geotiff.py envisat.tif


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;you should see an output telling you that it is &lt;code&gt;NOT a valid cloud optimized geotiff&lt;/code&gt; like this screenshot.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwn8w72tz30c02etitpl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwn8w72tz30c02etitpl.png" alt="not a valid cog file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convert the geotiff file into a cloud optimized geotiff file (COG).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to do that, we will use GDAL, make sure you have it installed on your machine. for GDAL 3.2 and later, it's a simple one line command, for older versions than 3.2, it's two separate commands. We will cover both cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GDAL &amp;gt;= 3.2
run this command on the geotiff file
```
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;gdal_translate envisat.tif envisat_cog.tif -of COG -co COMPRESS=LZW&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The larger the file, the more time it will take to convert it, at the end you should see an output like this.
![convert to cog gdal &amp;gt; 3.2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzzvhrqxfhc38z9dpmao.png)

Now let's try and validate the file again, run the validation command again, but this time on the **output** file:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;python validate_cloud_optimized_geotiff.py envisat_cog.tif&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;you should see and output message telling you that `envisat_cog.tif is a valid cloud optimized GeoTIFF` like this one.
![valid cog file 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eiko44bdr4zlnnkzqsog.png)

* GDAL &amp;lt; 3.2
We have to make this manually by creating the internal overviews, then create the tiles in the files.

Run the following command to create the internal overviews:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gdaladdo -r average envisat.tif 2 4 8 16&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;It can take some time depending on the file size, but when it completes, we are ready for the next step which is creating the tiles. Run the following command on the file:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gdal_translate envisat.tif envisat_cog.tif -co COMPRESS=LZW -co TILED=YES -co INTERLEAVE=BAND&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This command also can take some time depending on the file size, but when it completes, you should have a valid COG file. We can easily validate that, by running the validation script on the **output** file:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;python validate_cloud_optimized_geotiff.py envisat_cog.tif&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;It should tell you that `envisat_cog.tif is a valid cloud optimized GeoTIFF`

## Halfway done!

You can now have a break and bring in a cup of coffee ☕ (or tea) since we made some good progress here. We have our COG file ready to be served by GeoServer.

Let's continue.

GeoServer doesn't support COG files out of the box, luckily there is a community module that adds support to that.

- Go ahead and open GeoServer's [nightly build](https://build.geoserver.org/geoserver/) directory.

- Choose your version of GeoServer `2.16.x` `2.17.x` `2.18.x` `2.19.x`

- Open `community-latest`

- Search for the word `cog`, you should have only **1** search hit, which is a module named `geoserver-2.x-SNAPSHOT-cog-plugin.zip` where `x` is GeoServer minor version.

- Download the module's zip file and extract the content to GeoServer's `WEB-INF/lib` directory then **restart** GeoServer.

### Congratulations! GeoServer now supports COG

- Open up GeoServer's homepage (usually at localhost:8080/geoserver) and login with your credentials (usually admin:geoserver)

- From the left side menu, under `Data`, select `Workspaces`, then click on `Add new workspace`
![GeoServer Data menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kn8zi6sa1cwxh1dj7wun.png)
![Add new workspace](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hw4agfdayi7we3qsyrj6.png)

- Create a new workspace called `cog`
![cog workspace](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/not8cyvf0d2dqoct064u.png)

- Navigate to GeoServer's data directory, create a folder called `cogs` then copy and paste or cog file `envisat_cog.tif` into that directory.

- Back to GeoServer's console, from the left side menu, under `Data`, select `Stores`. Every geotiff (COG) file you publish is a complete store. click on `Add new store`.
![GeoServer Data menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kn8zi6sa1cwxh1dj7wun.png)
![Add new store](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0ffru7oc3c3okiezuti.png)

- From the long menu of GeoServer's data sources, under `Raster Data Sources`, click on `GeoTIFF`.
![New GeoTIFF](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46dwr55zmcy3fwmcdkqk.png)

- A wizard will appear, for `Workspace` select our newly created workspace called `cog`.
- For the `Data source name`, I will type `envisat`.
- For the `Description`, I will type `envisat_store`.
- Next to the `URL` field, click on the `Browse` button and select the `envisat_cog.tif` file.
![Browse for Tif file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewlgfilvautwe6kfxic0.png)
- Mark the checkbox `Cloud Optimized GeoTIFF (COG)`
Leave all the other settings as is, you should have something like this.
![Add new Raster Data Source](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9p33d405yln9eg8onrfi.png)
- Click `Save`

- You'll find yourself in the wizard that creates a new layer (that is a good thing!), and your new layer is ready to be published.
![New Layer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6jy5tftxwjis3szmaymp.png)
- Click on `Publish`

- The wizard for `Edit Layer` is opened automatically, I will change the layer name to `envisat` and the title to `Envisat`, then I will click `Save`.
![Save Layer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o0lppooiur0csk9w95m5.png)

- The layer is created and added to the layers list.
![Layer List](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dr8otzio88txjwbcekfb.png)

- Preview the layer from the `Layer Preview` menu item under `Data` from the left menu.
![Layer Preview Menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5tcsjaygh8gs1f04a0kr.png)

- Click on `OpenLayers`

It Does not matter how large your layer is, it will load up in seconds (or less), and when you zoom in/out it will load up almost instantly thanks to **COG**.

![Preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4puhsgwepmayw1wetn7y.png)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>geoserver</category>
      <category>cloudoptimizedgeotiff</category>
      <category>cog</category>
      <category>raster</category>
    </item>
    <item>
      <title>Ionic React Manual Dark Mode Switch</title>
      <dc:creator>Ibrahim Awad</dc:creator>
      <pubDate>Thu, 30 Apr 2020 11:21:20 +0000</pubDate>
      <link>https://dev.to/ibrahimawadhamid/ionic-react-manual-dark-mode-switch-3aad</link>
      <guid>https://dev.to/ibrahimawadhamid/ionic-react-manual-dark-mode-switch-3aad</guid>
      <description>&lt;p&gt;Hello there!&lt;br&gt;
With growing support for dark mode in native apps, developers are now looking to add it to their apps to support user preferences. Ionic makes it easy to change the themes of your app, including supporting &lt;a href="https://ionicframework.com/docs/theming/dark-mode"&gt;dark color schemes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In a normal scenario, when the user switches to &lt;strong&gt;Dark Mode&lt;/strong&gt; in their operating system (Android - iOS - Web), your application will switch automatically to the dark theme. This happens using &lt;strong&gt;Media Queries&lt;/strong&gt; and to be exact, one media query for the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme"&gt;user's preferred color scheme&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In my situation I want to have a manual switch in my application that the user can flip to turn on/off the &lt;strong&gt;Dark Mode&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9ubEZy-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/olf5bf6wrw0qc7jxqigo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9ubEZy-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/olf5bf6wrw0qc7jxqigo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's dive right into it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Steps:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; Create a new ionic/react project&lt;/li&gt;
&lt;li&gt; Modify the current theme variables to allow for manual Dark Mode switching&lt;/li&gt;
&lt;li&gt; Implement the controller to do the magic&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Create a new ionic/react project
&lt;/h3&gt;

&lt;p&gt;refering to the &lt;a href="https://ionicframework.com/docs/react/quickstart"&gt;official documentation&lt;/a&gt; of ionic, I will simply do the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @ionic/cli
ionic start AppWithDarkMode blank --type=react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open up your newly created project in your preferred IDE, I like &lt;a href="https://code.visualstudio.com/"&gt;Visual Studio Code&lt;/a&gt;, it is super lightweight and supports ton of extensions witch makes your development much easier and much faster.&lt;/p&gt;

&lt;p&gt;Now check if your application is running normally by going into the project directory and running &lt;code&gt;ionic serve&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd AppWithDarkMode
ionic serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your browser will open up at &lt;code&gt;http://localhost:8100/&lt;/code&gt; by default and you're supposed to see something similar to this&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JsjFTKOR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xx9xiqcvqgh08j0ewnav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JsjFTKOR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xx9xiqcvqgh08j0ewnav.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now moving to the next step.&lt;/p&gt;
&lt;h3&gt;
  
  
  Modify the current theme variables to allow for manual Dark Mode switching
&lt;/h3&gt;

&lt;p&gt;Open up the project in your IDE, under &lt;code&gt;src&lt;/code&gt; =&amp;gt; &lt;code&gt;theme&lt;/code&gt; there's a file called &lt;code&gt;variables.css&lt;/code&gt;, open that up.&lt;br&gt;
You can find two sections, one for the &lt;code&gt;:root&lt;/code&gt; tag, and another for the media query we talked about. Inside the media query, there are three sections &lt;code&gt;body&lt;/code&gt;, &lt;code&gt;.ios body&lt;/code&gt;, and &lt;code&gt;.md body&lt;/code&gt;. You can easily guess what these three sections are for. These are the dark theme colors for all different platforms running your application.&lt;/p&gt;

&lt;p&gt;Now &lt;strong&gt;copy&lt;/strong&gt; all those three sections (&lt;code&gt;body&lt;/code&gt;, &lt;code&gt;.ios body&lt;/code&gt;, and &lt;code&gt;.md body&lt;/code&gt;) outside of the media query and at the end of the file itself. Sure you can create a separate file and include that in your application, but that's up to you.&lt;/p&gt;

&lt;p&gt;Now simply add &lt;code&gt;.dark&lt;/code&gt; to each of the newly created &lt;code&gt;body&lt;/code&gt; tags so that they can be like this (&lt;code&gt;body.dark&lt;/code&gt;, &lt;code&gt;.ios body.dark&lt;/code&gt;, and &lt;code&gt;.md body.dark&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4QM0kc7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ea9etx2ly6mnbxmtssj1.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4QM0kc7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ea9etx2ly6mnbxmtssj1.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we're ready for our final step.&lt;/p&gt;
&lt;h3&gt;
  
  
  Implement the controller to do the magic
&lt;/h3&gt;

&lt;p&gt;I will begin by modifying the &lt;code&gt;Home.tsx&lt;/code&gt; file, which is the home page that displays in the app.&lt;br&gt;
My current/auto-generated &lt;code&gt;Home.tsx&lt;/code&gt; file looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Home: React.FC = () =&amp;gt; {
  return (
    &amp;lt;IonPage&amp;gt;
      &amp;lt;IonHeader&amp;gt;
        &amp;lt;IonToolbar&amp;gt;
          &amp;lt;IonTitle&amp;gt;Blank&amp;lt;/IonTitle&amp;gt;
        &amp;lt;/IonToolbar&amp;gt;
      &amp;lt;/IonHeader&amp;gt;
      &amp;lt;IonContent&amp;gt;
        &amp;lt;IonHeader collapse="condense"&amp;gt;
          &amp;lt;IonToolbar&amp;gt;
            &amp;lt;IonTitle size="large"&amp;gt;Blank&amp;lt;/IonTitle&amp;gt;
          &amp;lt;/IonToolbar&amp;gt;
        &amp;lt;/IonHeader&amp;gt;
        &amp;lt;ExploreContainer /&amp;gt;
      &amp;lt;/IonContent&amp;gt;
    &amp;lt;/IonPage&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will remove the second &lt;code&gt;IonHeader&lt;/code&gt; tag in the &lt;code&gt;IonContent&lt;/code&gt; and leave the &lt;code&gt;ExploreContainer&lt;/code&gt; component, so it will look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Home: React.FC = () =&amp;gt; {
  return (
    &amp;lt;IonPage&amp;gt;
      &amp;lt;IonHeader&amp;gt;
        &amp;lt;IonToolbar&amp;gt;
          &amp;lt;IonTitle&amp;gt;Blank&amp;lt;/IonTitle&amp;gt;
        &amp;lt;/IonToolbar&amp;gt;
      &amp;lt;/IonHeader&amp;gt;
      &amp;lt;IonContent&amp;gt;
        &amp;lt;ExploreContainer /&amp;gt;
      &amp;lt;/IonContent&amp;gt;
    &amp;lt;/IonPage&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we'll need a couple of imports. Please note that most of the following is to make the UI look good, the functionality itself is fairly simple.&lt;br&gt;
Now the imports will look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonList, IonItem, IonIcon, IonLabel, IonToggle} from "@ionic/react";
import { moon } from "ionicons/icons";
import ExploreContainer from "../components/ExploreContainer";
import "./Home.css";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use our newly imported components like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Home: React.FC = () =&amp;gt; {
  return (
    &amp;lt;IonPage&amp;gt;
      &amp;lt;IonHeader&amp;gt;
        &amp;lt;IonToolbar&amp;gt;
          &amp;lt;IonTitle&amp;gt;Blank&amp;lt;/IonTitle&amp;gt;
        &amp;lt;/IonToolbar&amp;gt;
      &amp;lt;/IonHeader&amp;gt;
      &amp;lt;IonContent&amp;gt;
        &amp;lt;IonList className="ion-margin-top"&amp;gt;
          &amp;lt;IonItem&amp;gt;
            &amp;lt;IonIcon slot="start" icon={moon} /&amp;gt;
            &amp;lt;IonLabel&amp;gt;Dark Mode&amp;lt;/IonLabel&amp;gt;
            &amp;lt;IonToggle
              slot="end"
              name="darkMode"
              onIonChange={toggleDarkModeHandler}
            /&amp;gt;
          &amp;lt;/IonItem&amp;gt;
        &amp;lt;/IonList&amp;gt;
        &amp;lt;ExploreContainer /&amp;gt;
      &amp;lt;/IonContent&amp;gt;
    &amp;lt;/IonPage&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can tell directly that it's complaining about &lt;code&gt;onIonChange={toggleDarkModeHandler}&lt;/code&gt;, that's because we haven't implemented that method yet.&lt;/p&gt;

&lt;p&gt;Go ahead and create that method inside the &lt;code&gt;Home&lt;/code&gt; component like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const toggleDarkModeHandler = () =&amp;gt; {
    document.body.classList.toggle("dark");
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like I said, the functionality itself is fairly simple.&lt;/p&gt;

&lt;p&gt;Now return to your browser, and you'll see that the switch is there and is working!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qAsAzAo5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xppwm7i8rp9pyejna41j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qAsAzAo5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xppwm7i8rp9pyejna41j.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Extra
&lt;/h3&gt;

&lt;p&gt;We can do a little bit of an extra styling to the icon so that it looks like this&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9ubEZy-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/olf5bf6wrw0qc7jxqigo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9ubEZy-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/olf5bf6wrw0qc7jxqigo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; In the &lt;code&gt;Home.css&lt;/code&gt; file add the following css classes.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.component-icon {
  border-radius: 50%;

  padding: 7px;
  height: 18px;
  width: 18px;

  margin-top: 5px;
  margin-bottom: 5px;
}

.component-icon-dark {
  background: var(--ion-color-step-850, #27323e);
  color: var(--ion-item-background, #fff);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And simply use the new CSS classes on the &lt;code&gt;IonIcon&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;IonIcon
    slot="start"
    icon={moon}
    className="component-icon component-icon-dark"
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it!&lt;/p&gt;

&lt;h3&gt;
  
  
  Complete &lt;code&gt;Home.tsx&lt;/code&gt; file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import {IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonList, IonItem, IonIcon, IonLabel, IonToggle} from "@ionic/react";
import { moon } from "ionicons/icons";
import ExploreContainer from "../components/ExploreContainer";
import "./Home.css";

const Home: React.FC = () =&amp;gt; {
  const toggleDarkModeHandler = () =&amp;gt; {
    document.body.classList.toggle("dark");
  };
  return (
    &amp;lt;IonPage&amp;gt;
      &amp;lt;IonHeader&amp;gt;
        &amp;lt;IonToolbar&amp;gt;
          &amp;lt;IonTitle&amp;gt;Blank&amp;lt;/IonTitle&amp;gt;
        &amp;lt;/IonToolbar&amp;gt;
      &amp;lt;/IonHeader&amp;gt;
      &amp;lt;IonContent&amp;gt;
        &amp;lt;IonList className="ion-margin-top"&amp;gt;
          &amp;lt;IonItem&amp;gt;
            &amp;lt;IonIcon
              slot="start" icon={moon} className="component-icon component-icon-dark" /&amp;gt;
            &amp;lt;IonLabel&amp;gt;Dark Mode&amp;lt;/IonLabel&amp;gt;
            &amp;lt;IonToggle slot="end" name="darkMode" onIonChange={toggleDarkModeHandler} /&amp;gt;
          &amp;lt;/IonItem&amp;gt;
        &amp;lt;/IonList&amp;gt;
        &amp;lt;ExploreContainer /&amp;gt;
      &amp;lt;/IonContent&amp;gt;
    &amp;lt;/IonPage&amp;gt;
  );
};

export default Home;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ionic</category>
      <category>react</category>
      <category>typescript</category>
      <category>darkmode</category>
    </item>
    <item>
      <title>Update/Publish Styles on GeoServer from Javascript using REST</title>
      <dc:creator>Ibrahim Awad</dc:creator>
      <pubDate>Wed, 29 Apr 2020 22:11:34 +0000</pubDate>
      <link>https://dev.to/ibrahimawadhamid/update-publish-styles-on-geoserver-from-javascript-using-rest-2gga</link>
      <guid>https://dev.to/ibrahimawadhamid/update-publish-styles-on-geoserver-from-javascript-using-rest-2gga</guid>
      <description>&lt;p&gt;Hi there!&lt;br&gt;
Do you want to publish or update some styles on &lt;a href="http://geoserver.org/"&gt;GeoServer&lt;/a&gt;, that's easy, check out the &lt;a href="https://docs.geoserver.org/latest/en/user/rest/styles.html"&gt;official documentation&lt;/a&gt; for that. After you read it and can't use it in your javascript code, come here, this post will help you.&lt;/p&gt;

&lt;p&gt;I'll skip the unnecessary chat about various situations you might need this and get right to it.&lt;br&gt;
I'm using &lt;code&gt;axios&lt;/code&gt; to handle my connections (because I like it :D), but you can do it with other libraries or even with vanilla JS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update an existing style (using PUT)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;   First prepare the &lt;code&gt;StyleContent&lt;/code&gt; which is the content of the style file as if you normally would upload it through geoserver interface.&lt;/li&gt;
&lt;li&gt;   Make sure you have the right access, I'm using default username and password for geoserver &lt;code&gt;admin&lt;/code&gt; and &lt;code&gt;geoserver&lt;/code&gt; for this.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const geoserverURL = 'http://{GEOSERVER_HOST}/geoserver/rest/workspaces/{WORKSPACE}/styles/{STYLE_NAME}'
axios({
    method: 'put',
    url: geoserverURL,
    data: StyleContent,
    auth: {
        username: 'admin',
        password: 'geoserver'
    },
    headers: {'Content-Type': 'application/vnd.ogc.se+xml'}
}).then((response) =&amp;gt; {}, (error) =&amp;gt; {console.log(error);});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Publish a new style
&lt;/h2&gt;

&lt;p&gt;Guess what happens if you change the method from &lt;code&gt;put&lt;/code&gt; to &lt;code&gt;post&lt;/code&gt; from the previous code? That's correct! you publish a new style to geoserver.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>geoserver</category>
      <category>gis</category>
      <category>style</category>
    </item>
    <item>
      <title>How to create a private route in React (Route Guard) - example: for authenticated users only</title>
      <dc:creator>Ibrahim Awad</dc:creator>
      <pubDate>Wed, 29 Apr 2020 02:52:37 +0000</pubDate>
      <link>https://dev.to/ibrahimawadhamid/how-to-create-a-private-route-in-react-route-guard-example-for-authenticated-users-only-kin</link>
      <guid>https://dev.to/ibrahimawadhamid/how-to-create-a-private-route-in-react-route-guard-example-for-authenticated-users-only-kin</guid>
      <description>&lt;p&gt;Hello there!&lt;br&gt;
It always happen when you're building a react app and configuring your routes, you find out that you don't want your routes to be all public all the time. Perhaps you want to make some routes accessible only for authenticated/authorized users, or make them available at a condition that makes sense to your business logic.&lt;/p&gt;

&lt;p&gt;I have some good news for you, you don't need some fancy third-party library to achieve that, or even be an expert in routing techniques in single-page-applications.&lt;br&gt;
I will demonstrate a simple solution that you can easily configure into your application logic.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  A working React application with your routes configured and ready to use.&lt;/li&gt;
&lt;li&gt;  A good cup of coffee (only if you're a coffee fan).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;I have my routes here all setup and working fine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Route  path="/page/home"  component={Home}  exact  /&amp;gt;
&amp;lt;Route  path="/page/news"  component={News}  exact  /&amp;gt;
&amp;lt;Route  path="/page/login"  component={Login}  exact  /&amp;gt;
&amp;lt;Route  path="/page/profile"  component={Profile}  exact  /&amp;gt;
&amp;lt;Redirect  from="/"  to="/page/home"  exact  /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The only problem with these routes is that any one can access the URL &lt;code&gt;/page/profile&lt;/code&gt; and I only want that route to be available when the user is authenticated, otherwise I want him to be redirected to the login page &lt;code&gt;/page/login&lt;/code&gt; first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;I will create a simple &lt;code&gt;jsx&lt;/code&gt; or &lt;code&gt;tsx&lt;/code&gt; component (works for React JS or Typescript) that wraps around the &lt;code&gt;Route&lt;/code&gt; component from the &lt;code&gt;react-router-dom&lt;/code&gt; library. It will check for my given condition first, if that's true, it will render that component like it's supposed to do, otherwise it will redirect me to the login page.&lt;/p&gt;

&lt;p&gt;Now let's take a look at my component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import  React from  "react";
import { Route, Redirect } from  "react-router-dom";

const  PrivateRoute: React.FC&amp;lt;{
        component: React.FC;
        path: string;
        exact: boolean;
    }&amp;gt; = (props) =&amp;gt; {

    const condition = performValidationHere();

    return  condition ? (&amp;lt;Route  path={props.path}  exact={props.exact} component={props.component} /&amp;gt;) : 
        (&amp;lt;Redirect  to="/page/login"  /&amp;gt;);
};
export  default  PrivateRoute;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Code walk-through
&lt;/h2&gt;

&lt;p&gt;The functional component expects three(3) props:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The component to render in case of a valid condition &lt;code&gt;Profile Page for example&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  The path to that component &lt;code&gt;/page/profile for example&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Any additional parameters like the &lt;code&gt;exact&lt;/code&gt; attribute&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Route  path="/page/home"  component={Home}  exact  /&amp;gt;
&amp;lt;Route  path="/page/news"  component={News}  exact  /&amp;gt;
&amp;lt;Route  path="/page/login"  component={Login}  exact  /&amp;gt;
&amp;lt;PrivateRoute  path="/page/profile"  component={Profile}  exact  /&amp;gt;
&amp;lt;Redirect  from="/"  to="/page/home"  exact  /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it! you've done it, you now have your routes protected.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
      <category>reactrouterdom</category>
      <category>reactrouterguard</category>
    </item>
  </channel>
</rss>
