diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index cd7535d..51ed6ec 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -11,6 +11,7 @@ repos:
     rev: "v4.6.0"
     hooks:
       - id: "check-added-large-files"
+        args: ["--maxkb=20000"]
       - id: "check-ast"
       - id: "check-byte-order-marker"
       - id: "check-docstring-first"
diff --git a/notebooks/TELEMAC.ipynb b/notebooks/TELEMAC.ipynb
new file mode 100644
index 0000000..d93cba8
--- /dev/null
+++ b/notebooks/TELEMAC.ipynb
@@ -0,0 +1,134 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# ensure that the Selafin engine is available\n",
+    "%pip install xarray-selafin"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# main imports\n",
+    "import holoviews as hv\n",
+    "hv.extension(\"bokeh\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import thalassa\n",
+    "from thalassa import api"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "malpasset = api.open_dataset('../tests/data/r2d_malpasset-char_p2.slf', source_crs = None) # default EPSG is 4326\n",
+    "malpasset"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The `Malpasset` mesh is not georeferentiated in a known local coordinate system\n",
+    "\n",
+    "We'll avoid activating the default EPSG (4326) in order to be able to view it. \n",
+    "\n",
+    "by imposing `source_crs = None`, we disable: \n",
+    " * reprojection done on the mesh (Thalassa reprojects  automatically to Mercator to superpose meshes with WMS tiles) \n",
+    " * the tiling visualization"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# The trimesh is the most basic object. This is what you need to create all the others graphs\n",
+    "# It is on this object that you specify the timestamp and/or the layer.\n",
+    "trimesh = api.create_trimesh(malpasset.isel(time=0), variable='H')\n",
+    "\n",
+    "# The nodes of the mesh (without triangles, just the points!)\n",
+    "nodes = api.get_nodes(trimesh)\n",
+    "\n",
+    "# The wireframe is the representation of the mesh\n",
+    "wireframe = api.get_wireframe(trimesh)\n",
+    "\n",
+    "# The raster object is the basic Map that visualizes the variable. \n",
+    "# You can specify things like the colorbar limits and/or the extents\n",
+    "#raster = api.get_raster(trimesh, clim_min=0, clim_max=15)\n",
+    "raster = api.get_raster(trimesh).opts(cmap = 'rainbow')\n",
+    "\n",
+    "(raster * wireframe).opts(width=900, height=600)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "To show another example using a known CRS, here is the `Manche` mesh from the TOMAWAC examples:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "manche = api.open_dataset('../tests/data/r2d.V1P3.slf') # use the default EPSG (4326)\n",
+    "manche"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "thalassa.plot(\n",
+    "    manche.isel(time = -1), \n",
+    "    variable='HAUTEUR_HM0', \n",
+    "    show_mesh = True, \n",
+    "    cmap = 'rainbow'\n",
+    ").opts(width=900, height = 900)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": ".venv",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.10.13"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/poetry.lock b/poetry.lock
index 8519ca6..19c0d03 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
 
 [[package]]
 name = "appnope"
@@ -1040,13 +1040,13 @@ test = ["fiona[s3]", "pytest (>=7)", "pytest-cov", "pytz"]
 
 [[package]]
 name = "flox"
-version = "0.9.7"
+version = "0.9.8"
 description = "GroupBy operations for dask.array"
 optional = false
 python-versions = ">=3.9"
 files = [
-    {file = "flox-0.9.7-py3-none-any.whl", hash = "sha256:0e15d678c5f3d46fe5c6481519d01ceae40a111133b110e80f3b274881af8497"},
-    {file = "flox-0.9.7.tar.gz", hash = "sha256:baa7c0aa9b2836f5cf1b283ce918cf3d61dc9ff0af8bda026a598ba5cc0b7c68"},
+    {file = "flox-0.9.8-py3-none-any.whl", hash = "sha256:9a74daff7e47d105c98fa506f25c55b52c38374e96f046ca906b49272baec03f"},
+    {file = "flox-0.9.8.tar.gz", hash = "sha256:1236efb869ae3b9dec2066605dbacebae571721ab7d37507cbb0d96bbc3e47fd"},
 ]
 
 [package.dependencies]
@@ -1475,6 +1475,27 @@ qtconsole = ["qtconsole"]
 test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"]
 test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"]
 
+[[package]]
+name = "ipywidgets"
+version = "8.1.3"
+description = "Jupyter interactive widgets"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "ipywidgets-8.1.3-py3-none-any.whl", hash = "sha256:efafd18f7a142248f7cb0ba890a68b96abd4d6e88ddbda483c9130d12667eaf2"},
+    {file = "ipywidgets-8.1.3.tar.gz", hash = "sha256:f5f9eeaae082b1823ce9eac2575272952f40d748893972956dc09700a6392d9c"},
+]
+
+[package.dependencies]
+comm = ">=0.1.3"
+ipython = ">=6.1.0"
+jupyterlab-widgets = ">=3.0.11,<3.1.0"
+traitlets = ">=4.3.1"
+widgetsnbextension = ">=4.0.11,<4.1.0"
+
+[package.extras]
+test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"]
+
 [[package]]
 name = "jedi"
 version = "0.19.1"
@@ -1546,6 +1567,26 @@ files = [
 [package.dependencies]
 referencing = ">=0.31.0"
 
+[[package]]
+name = "jupyter-bokeh"
+version = "4.0.4"
+description = "A Jupyter extension for rendering Bokeh content."
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "jupyter_bokeh-4.0.4-py3-none-any.whl", hash = "sha256:5aba6ebf1b0db56b613c1d197fb54b8c3260363864bd6a24b2c01024e8c5b328"},
+    {file = "jupyter_bokeh-4.0.4.tar.gz", hash = "sha256:f70b70b55c2e53b7d34bf6a244d489dd6b7824d0318790181463f481cc2cd1f8"},
+]
+
+[package.dependencies]
+bokeh = "==3.*"
+ipywidgets = "==8.*"
+
+[package.extras]
+all = ["jupyter-bokeh[build]", "jupyter-bokeh[tests]"]
+build = ["jupyterlab (>=4.0,<5.0)", "setuptools (>=40.8.0)"]
+tests = ["flake8", "pytest"]
+
 [[package]]
 name = "jupyter-client"
 version = "8.6.2"
@@ -1589,6 +1630,17 @@ traitlets = ">=5.3"
 docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"]
 test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"]
 
+[[package]]
+name = "jupyterlab-widgets"
+version = "3.0.11"
+description = "Jupyter interactive widgets for JupyterLab"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "jupyterlab_widgets-3.0.11-py3-none-any.whl", hash = "sha256:78287fd86d20744ace330a61625024cf5521e1c012a352ddc0a3cdc2348becd0"},
+    {file = "jupyterlab_widgets-3.0.11.tar.gz", hash = "sha256:dd5ac679593c969af29c9bed054c24f26842baa51352114736756bc035deee27"},
+]
+
 [[package]]
 name = "kiwisolver"
 version = "1.4.5"
@@ -2242,7 +2294,6 @@ files = [
     {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"},
     {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"},
     {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"},
-    {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"},
 ]
 
 [[package]]
@@ -2658,7 +2709,6 @@ files = [
     {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"},
     {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"},
     {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"},
-    {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"},
     {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"},
     {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"},
     {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"},
@@ -3665,13 +3715,13 @@ files = [
 
 [[package]]
 name = "requests"
-version = "2.32.2"
+version = "2.32.3"
 description = "Python HTTP for Humans."
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "requests-2.32.2-py3-none-any.whl", hash = "sha256:fc06670dd0ed212426dfeb94fc1b983d917c4f9847c863f313c9dfaaffb7c23c"},
-    {file = "requests-2.32.2.tar.gz", hash = "sha256:dd951ff5ecf3e3b3aa26b40703ba77495dab41da839ae72ef3c8e5d8e2433289"},
+    {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
+    {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
 ]
 
 [package.dependencies]
@@ -4187,6 +4237,17 @@ files = [
 docs = ["Sphinx (>=1.7.5)", "pylons-sphinx-themes"]
 testing = ["coverage", "pytest (>=3.1.0)", "pytest-cov", "pytest-xdist"]
 
+[[package]]
+name = "widgetsnbextension"
+version = "4.0.11"
+description = "Jupyter interactive widgets for Jupyter Notebook"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "widgetsnbextension-4.0.11-py3-none-any.whl", hash = "sha256:55d4d6949d100e0d08b94948a42efc3ed6dfdc0e9468b2c4b128c9a2ce3a7a36"},
+    {file = "widgetsnbextension-4.0.11.tar.gz", hash = "sha256:8b22a8f1910bfd188e596fe7fc05dcbd87e810c8a4ba010bdb3da86637398474"},
+]
+
 [[package]]
 name = "xarray"
 version = "2024.5.0"
@@ -4302,4 +4363,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more
 [metadata]
 lock-version = "2.0"
 python-versions = ">=3.9, <4.0"
-content-hash = "f57d757affff5478d7d54e7d4c3a4388d6059d661269eb002822c3f73e2dabf9"
+content-hash = "d5dc607682c3625df46fbf2132a55610aa9f22b9ed0a6174d7b5f089b55c0ccc"
diff --git a/pyproject.toml b/pyproject.toml
index 2d4353d..a6a7622 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -44,6 +44,7 @@ xarray = {version = "*", extras = ["io", "accel"]}
 covdefaults = "*"
 ipykernel = "*"
 ipython = "*"
+jupyter-bokeh = "*"
 mypy = ">=1"
 nbmake = "*"
 pandas-stubs = "*"
diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt
index 05fbd24..c64cb44 100644
--- a/requirements/requirements-dev.txt
+++ b/requirements/requirements-dev.txt
@@ -39,7 +39,7 @@ executing==2.0.1 ; python_version >= "3.9" and python_version < "4.0"
 fasteners==0.19 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "emscripten"
 fastjsonschema==2.19.1 ; python_version >= "3.9" and python_version < "4.0"
 fiona==1.9.6 ; python_version >= "3.9" and python_version < "4.0"
-flox==0.9.7 ; python_version >= "3.9" and python_version < "4.0"
+flox==0.9.8 ; python_version >= "3.9" and python_version < "4.0"
 fonttools==4.52.4 ; python_version >= "3.9" and python_version < "4.0"
 fsspec==2024.5.0 ; python_version >= "3.9" and python_version < "4.0"
 future==1.0.0 ; python_version >= "3.9" and python_version < "4.0"
@@ -56,12 +56,15 @@ importlib-resources==6.4.0 ; python_version >= "3.9" and python_version < "3.10"
 iniconfig==2.0.0 ; python_version >= "3.9" and python_version < "4.0"
 ipykernel==6.29.4 ; python_version >= "3.9" and python_version < "4.0"
 ipython==8.18.1 ; python_version >= "3.9" and python_version < "4.0"
+ipywidgets==8.1.3 ; python_version >= "3.9" and python_version < "4.0"
 jedi==0.19.1 ; python_version >= "3.9" and python_version < "4.0"
 jinja2==3.1.4 ; python_version >= "3.9" and python_version < "4.0"
 jsonschema-specifications==2023.12.1 ; python_version >= "3.9" and python_version < "4.0"
 jsonschema==4.22.0 ; python_version >= "3.9" and python_version < "4.0"
+jupyter-bokeh==4.0.4 ; python_version >= "3.9" and python_version < "4.0"
 jupyter-client==8.6.2 ; python_version >= "3.9" and python_version < "4.0"
 jupyter-core==5.7.2 ; python_version >= "3.9" and python_version < "4.0"
+jupyterlab-widgets==3.0.11 ; python_version >= "3.9" and python_version < "4.0"
 kiwisolver==1.4.5 ; python_version >= "3.9" and python_version < "4.0"
 linkify-it-py==2.0.3 ; python_version >= "3.9" and python_version < "4.0"
 llvmlite==0.42.0 ; python_version >= "3.9" and python_version < "4.0"
@@ -138,7 +141,7 @@ pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4.0"
 pyzmq==26.0.3 ; python_version >= "3.9" and python_version < "4.0"
 referencing==0.35.1 ; python_version >= "3.9" and python_version < "4.0"
 regex==2024.5.15 ; python_version >= "3.9" and python_version < "4.0"
-requests==2.32.2 ; python_version >= "3.9" and python_version < "4.0"
+requests==2.32.3 ; python_version >= "3.9" and python_version < "4.0"
 rpds-py==0.18.1 ; python_version >= "3.9" and python_version < "4.0"
 scipy==1.13.1 ; python_version >= "3.9" and python_version < "4.0"
 shapely==2.0.4 ; python_version >= "3.9" and python_version < "4.0"
@@ -162,6 +165,7 @@ watchdog==4.0.1 ; python_version >= "3.9" and python_version < "4.0"
 wcwidth==0.2.13 ; python_version >= "3.9" and python_version < "4.0"
 webencodings==0.5.1 ; python_version >= "3.9" and python_version < "4.0"
 webob==1.8.7 ; python_version >= "3.9" and python_version < "3.10"
+widgetsnbextension==4.0.11 ; python_version >= "3.9" and python_version < "4.0"
 xarray-selafin==0.1.6 ; python_version >= "3.9" and python_version < "4.0"
 xarray==2024.5.0 ; python_version >= "3.9" and python_version < "4.0"
 xarray[accel,io]==2024.5.0 ; python_version >= "3.9" and python_version < "4.0"
diff --git a/requirements/requirements.txt b/requirements/requirements.txt
index 6a5599c..fdffb21 100644
--- a/requirements/requirements.txt
+++ b/requirements/requirements.txt
@@ -24,7 +24,7 @@ distributed==2024.5.1 ; python_version >= "3.9" and python_version < "4.0"
 docopt==0.6.2 ; python_version < "3.10" and python_version >= "3.9"
 fasteners==0.19 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "emscripten"
 fiona==1.9.6 ; python_version >= "3.9" and python_version < "4.0"
-flox==0.9.7 ; python_version >= "3.9" and python_version < "4.0"
+flox==0.9.8 ; python_version >= "3.9" and python_version < "4.0"
 fonttools==4.52.4 ; python_version >= "3.9" and python_version < "4.0"
 fsspec==2024.5.0 ; python_version >= "3.9" and python_version < "4.0"
 future==1.0.0 ; python_version >= "3.9" and python_version < "4.0"
@@ -78,7 +78,7 @@ python-dateutil==2.9.0.post0 ; python_version >= "3.9" and python_version < "4.0
 pytz==2024.1 ; python_version >= "3.9" and python_version < "4.0"
 pyviz-comms==3.0.2 ; python_version >= "3.9" and python_version < "4.0"
 pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4.0"
-requests==2.32.2 ; python_version >= "3.9" and python_version < "4.0"
+requests==2.32.3 ; python_version >= "3.9" and python_version < "4.0"
 scipy==1.13.1 ; python_version >= "3.9" and python_version < "4.0"
 shapely==2.0.4 ; python_version >= "3.9" and python_version < "4.0"
 six==1.16.0 ; python_version >= "3.9" and python_version < "4.0"
diff --git a/tests/api_test.py b/tests/api_test.py
index c482ad0..e3f8fc2 100644
--- a/tests/api_test.py
+++ b/tests/api_test.py
@@ -9,17 +9,19 @@
 from thalassa import normalization
 
 ADCIRC_NC = DATA_DIR / "fort.63.nc"
-SELAFIN = DATA_DIR / "iceland.slf"
+SELAFIN1 = DATA_DIR / "r2d_malpasset-char_p2.slf"
+SELAFIN2 = DATA_DIR / "r2d.V1P3.slf"
 
 @pytest.mark.parametrize(
-    "file,variable",
+    "file,variable,crs",
     [
-        pytest.param(ADCIRC_NC, "zeta"),
-        pytest.param(SELAFIN, "S"),
+        pytest.param(ADCIRC_NC, "zeta", 4326),
+        pytest.param(SELAFIN1, "S", None),
+        pytest.param(SELAFIN2, "HAUTEUR_HM0", 4326),
     ],
 )
-def test_main_api(file, variable):
-    ds = api.open_dataset(file)
+def test_main_api(file, variable, crs):
+    ds = api.open_dataset(file, source_crs=crs)
     assert normalization.is_generic(ds)
 
     # Create objects
@@ -37,7 +39,7 @@ def test_main_api(file, variable):
     hv.render(tap_ts, backend="bokeh")
     hv.render(wireframe, backend="bokeh")
 
-    assert isinstance(nodes, gv.Points)
+    assert isinstance(nodes, (gv.Points, hv.Points))
     assert isinstance(pointer_ts, hv.DynamicMap)
     assert isinstance(raster, hv.DynamicMap)
     assert isinstance(tap_ts, hv.DynamicMap)
@@ -45,16 +47,17 @@ def test_main_api(file, variable):
 
 
 @pytest.mark.parametrize(
-    "file,variable",
+    "file,variable,crs",
     [
-        pytest.param(ADCIRC_NC, "zeta"),
-        pytest.param(SELAFIN, "S"),
+        pytest.param(ADCIRC_NC, "zeta", 4326),
+        pytest.param(SELAFIN1, "S", None),
+        pytest.param(SELAFIN2, "HAUTEUR_HM0", 4326),
     ],
 )
-def test_create_trimesh(file, variable):
-    ds = api.open_dataset(file)
+def test_create_trimesh(file, variable, crs):
+    ds = api.open_dataset(file, source_crs=crs)
     trimesh = api.create_trimesh(ds, variable=variable)
-    assert isinstance(trimesh, gv.TriMesh)
+    assert isinstance(trimesh, (gv.TriMesh, hv.TriMesh))
 
 
 def test_get_tiles():
diff --git a/tests/data/iceland.slf b/tests/data/iceland.slf
deleted file mode 100644
index caefc23..0000000
Binary files a/tests/data/iceland.slf and /dev/null differ
diff --git a/tests/data/r2d.V1P3.slf b/tests/data/r2d.V1P3.slf
new file mode 100644
index 0000000..0f61852
Binary files /dev/null and b/tests/data/r2d.V1P3.slf differ
diff --git a/tests/data/r2d_malpasset-char_p2.slf b/tests/data/r2d_malpasset-char_p2.slf
new file mode 100644
index 0000000..0dec9b8
Binary files /dev/null and b/tests/data/r2d_malpasset-char_p2.slf differ
diff --git a/tests/normalization_test.py b/tests/normalization_test.py
index ca13b7e..07031a9 100644
--- a/tests/normalization_test.py
+++ b/tests/normalization_test.py
@@ -12,7 +12,8 @@
     "ds,expected_fmt",
     [
         pytest.param(api.open_dataset(DATA_DIR / "fort.63.nc", normalize=False), THALASSA_FORMATS.ADCIRC, id="ADCIRC"),
-        pytest.param(api.open_dataset(DATA_DIR / "iceland.slf", normalize=False), THALASSA_FORMATS.TELEMAC, id="TELEMAC"),
+        pytest.param(api.open_dataset(DATA_DIR / "r2d_malpasset-char_p2.slf", normalize=False, source_crs=4326), THALASSA_FORMATS.TELEMAC, id="TELEMAC"),
+        pytest.param(api.open_dataset(DATA_DIR / "r2d.V1P3.slf", normalize=False), THALASSA_FORMATS.TELEMAC, id="TELEMAC"),
         pytest.param(xr.Dataset(), THALASSA_FORMATS.UNKNOWN, id="Unknown"),
     ],
 )
@@ -25,7 +26,8 @@ def test_infer_format(ds, expected_fmt):
     "path,expected",
     [
         pytest.param(DATA_DIR / "fort.63.nc", True, id="ADCIRC"),
-        pytest.param(DATA_DIR / "iceland.slf", True, id="TELEMAC"),
+        pytest.param(DATA_DIR / "r2d_malpasset-char_p2.slf", True, id="TELEMAC"),
+        pytest.param(DATA_DIR / "r2d.V1P3.slf", True, id="TELEMAC"),
         pytest.param(__file__, False, id="Unknown"),
     ],
 )
diff --git a/thalassa/api.py b/thalassa/api.py
index 051758b..7a9055c 100644
--- a/thalassa/api.py
+++ b/thalassa/api.py
@@ -59,6 +59,7 @@ def _resolve_ranges(x_range: tuple[float, float] | None, y_range: tuple[float, f
 def open_dataset(
     path: str | os.PathLike[str],
     normalize: bool = True,
+    source_crs: int = 4326,
     **kwargs: dict[str, T.Any],
 ) -> xarray.Dataset:
     """
@@ -86,6 +87,7 @@ def open_dataset(
         path: The path to the dataset file (netCDF, zarr, grib)
         normalize: Boolean flag indicating whether the dataset should be converted/normalized to the "Thalassa schema".
             Normalization is currently only supported for ``SCHISM``, ``TELEMAC``,  and ``ADCIRC`` netcdf files.
+        source_crs: The coordinate system of the dataset (default is WGS84)
         kwargs: The ``kwargs`` are being passed through to ``xarray.open_dataset``.
 
     """
@@ -99,7 +101,7 @@ def open_dataset(
     with warnings.catch_warnings(record=True):
         ds = xr.open_dataset(path, **(default_kwargs | kwargs))
     if normalize:
-        ds = normalization.normalize(ds)
+        ds = normalization.normalize(ds, source_crs=source_crs)
     return ds
 
 
@@ -127,10 +129,11 @@ def create_trimesh(
             If a trimesh object is passed, then return it immediately.
         variable: The data variable we want to visualize
     """
+    import holoviews as hv
     import geoviews as gv
     from cartopy import crs
 
-    if isinstance(ds_or_trimesh, gv.TriMesh):
+    if isinstance(ds_or_trimesh, (gv.TriMesh, hv.TriMesh)):
         # This is already a trimesh, nothing to do
         return ds_or_trimesh
     else:
@@ -142,19 +145,27 @@ def create_trimesh(
         columns.append(variable)
     points_df = ds[columns].to_dataframe()
     # Convert the data to Google Mercator. This makes interactive usage faster
-    transformer = _get_transformer(from_crs="EPSG:4326", to_crs="EPSG:3857")
-    tlon, tlat = transformer.transform(points_df.lon, points_df.lat)
-    points_df = points_df.assign(lon=tlon, lat=tlat)
-    # Create the geoviews object
-    kwargs = dict(data=points_df, kdims=["lon", "lat"], crs=crs.GOOGLE_MERCATOR)
-    if variable:
-        kwargs["vdims"] = [variable]
-    points_gv = gv.Points(**kwargs)
-    # Create the trimesh
-    if variable:
-        trimesh = gv.TriMesh((ds.triface_nodes.data, points_gv), name=variable)
+    if ds.attrs["source_crs"]:
+        transformer = _get_transformer(from_crs=ds.attrs["source_crs"], to_crs="EPSG:3857")
+        tlon, tlat = transformer.transform(points_df.lon, points_df.lat)
+        points_df = points_df.assign(lon=tlon, lat=tlat)
+        # Create the geoviews object
+        kwargs = dict(data=points_df, kdims=["lon", "lat"], crs=crs.GOOGLE_MERCATOR)
+        if variable:
+            kwargs["vdims"] = [variable]
+        points_gv = gv.Points(**kwargs)
+        # Create the trimesh
+        if variable:
+            trimesh = gv.TriMesh((ds.triface_nodes.data, points_gv), name=variable)
+        else:
+            trimesh = gv.TriMesh((ds.triface_nodes.data, points_gv))
     else:
-        trimesh = gv.TriMesh((ds.triface_nodes.data, points_gv))
+        points_gv = hv.Points(data=points_df, kdims=["lon", "lat"])
+        # Create the trimesh
+        if variable:
+            trimesh = hv.TriMesh((ds.triface_nodes.data, points_gv), name=variable)
+        else:
+            trimesh = hv.TriMesh((ds.triface_nodes.data, points_gv))
     return trimesh
 
 
@@ -184,19 +195,39 @@ def get_nodes(
     """Return a ``DynamicMap`` with the nodes of the mesh."""
     from cartopy import crs
     import geoviews as gv
+    import holoviews as hv
 
     trimesh = create_trimesh(ds_or_trimesh)
+    # determine if there is a crs transformation or not
+    if isinstance(ds_or_trimesh, (gv.TriMesh, hv.TriMesh)):
+        if isinstance(ds_or_trimesh, gv.TriMesh):
+            crs_transform = True
+        else:
+            crs_transform = False
+    else:
+        if ds_or_trimesh.attrs["source_crs"]:
+            crs_transform = True
+        else:
+            crs_transform = False
+
     kwargs: dict[str, T.Any] = {}
     _resolve_ranges(x_range=x_range, y_range=y_range, kwargs=kwargs)
     tools = ["crosshair"]
     if hover:
         tools.append("hover")
-    points = gv.Points(
-        trimesh.nodes.data.rename(columns={"index": "node"}),
-        kdims=["lon", "lat"],
-        vdims=["node"],
-        crs=crs.GOOGLE_MERCATOR,
-    )
+    if crs_transform:
+        points = gv.Points(
+            trimesh.nodes.data.rename(columns={"index": "node"}),
+            kdims=["lon", "lat"],
+            vdims=["node"],
+            crs=crs.GOOGLE_MERCATOR,
+        )
+    else:
+        points = hv.Points(
+            trimesh.nodes.data.rename(columns={"index": "node"}),
+            kdims=["lon", "lat"],
+            vdims=["node"],
+        )
     return points.opts(tools=tools, size=size, title=title, color="green")
 
 
@@ -274,7 +305,6 @@ def get_hover(variable: str) -> bokeh.models.HoverTool:
     return hover
 
 
-
 def _get_stream_timeseries(
     ds: xarray.Dataset,
     variable: str,
@@ -341,7 +371,7 @@ def callback(x: float, y: float) -> holoviews.Curve:
 def get_station_timeseries(
     stations: xarray.Dataset,
     pins: geoviews.DynamicMap,
-) -> holoviews.DynamicMap:   # pragma: no cover
+) -> holoviews.DynamicMap:  # pragma: no cover
     import holoviews as hv
     import pandas as pd
 
diff --git a/thalassa/normalization.py b/thalassa/normalization.py
index df2d306..3adeacc 100644
--- a/thalassa/normalization.py
+++ b/thalassa/normalization.py
@@ -184,7 +184,7 @@ def normalize_telemac(ds: xarray.Dataset) -> xarray.Dataset:
 
     # TELEMAC output uses one-based indices for `face_nodes`
     # Let's ensure that we use zero-based indices everywhere.
-    ds[CONNECTIVITY] = ((FACE_DIM, VERTICE_DIM), ds.attrs['ikle2'] - 1)
+    ds[CONNECTIVITY] = ((FACE_DIM, VERTICE_DIM), ds.attrs["ikle2"] - 1)
     return ds
 
 
@@ -227,7 +227,7 @@ def normalize_adcirc(ds: xarray.Dataset) -> xarray.Dataset:
 }
 
 
-def normalize(ds: xarray.Dataset) -> xarray.Dataset:
+def normalize(ds: xarray.Dataset, source_crs: int = 4326) -> xarray.Dataset:
     """
     Normalize the `dataset` i.e. convert it to the "Thalassa Schema".
 
@@ -243,12 +243,14 @@ def normalize(ds: xarray.Dataset) -> xarray.Dataset:
 
     Parameters:
         ds: The dataset we want to convert.
+        source_crs: The coordinate system of the dataset (default is WGS84)
 
     """
     logger.debug("Dataset normalization: Started")
     fmt = infer_format(ds)
     normalizer_func = NORMALIZE_DISPATCHER[fmt]
     normalized_ds = normalizer_func(ds)
+    normalized_ds.attrs["source_crs"] = source_crs
     # Handle quad elements
     # Splitting quad elements to triangles, means that the number of faces increases
     # There are two options: