npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eehitus-3d-twin

v1.12.6

Published

A react component library for displaying multidimensional data.

Readme

eehitus-3d-twin library

The 3D Map of Estonia. The library is developed to work inside the E-Ehitus application ecosystem and can't be deployed independetly,


Table of Contents


Getting started with development

Prerequisites

  • Node.js (v18.20.6)
  • Yarn (v1.x)

Running locally

  • npm i yarn -g - If you don't have yarn installed locally for given node version
  • yarn install
  • yarn start

Local development

yarn start opens http://localhost:3000

You have to look for BrowserRouter definition to find the urls you can navigate to. Usually can be found at ./src/App.tsx or in the component rendered inside it.

  • ./public/config.js contains all the endpoint URL-s for different microservices.
    • Default endpoint should end with /v1
    • You can specify a certain API to point to your projects API /project_ingress

Development patterns overview


Common components

  • eehitus-ui-extras
    • New common business logic components or enums, should be added to this library
  • TEDI library - E-Ehitus is moving to use Estonian TEDI library for react.
    • New features should be developed using them, if possible.
  • ehr-components Old components
    • These are old components and you should not create new functionality with them if possible.
  • eehitus-visuaal eehitus-ui has usage of global styles
    • When making changes there, make sure your change does not have impact to the rest of the UI libraries

Form validation

For form validation we use Yup.

If you have not used it before look find examples used in eehitus-document-ui.

For an Example find usage of: useYupValidation


Translations

All the translations exist in ./src/translations

Webpack at build time merges all the translations into 3 specific files:

  • example_project_name_et.json
  • example_project_name_en.json
  • example_project_name_ru.json

To add new translation files under ./src/translations

Follow that the file ends with *_et.json pattern


API requests

We use axios and we generate the entire API interface for all service requests using OpenApi Generator.

The API clients are located in ./src/services

Generating API with OpenApi Generator

openapi-generator version = 6.6.0

version 6 is required for axios 0.x

$ npm install -g @openapitools/openapi-generator-cli
$ openapi-generator-cli version-manager set 6

If backend is running and openapi doc is accessible (change the port to your matching BE running port)

$ openapi-generator-cli generate -i  http://localhost:9000/v3/api-docs -g typescript-axios --additional-properties=modelPropertyNaming=original --type-mappings=DateTime=Date --type-mappings=object=any

If you need to update service clients with master yaml

  • Find the yaml in Gitlab swagger project and download it
  • Create a new folder
  • Open terminal in the same folder with the yaml
$ openapi-generator-cli generate -i rename-this-to-your-file.yaml -g typescript-axios --additional-properties=modelPropertyNaming=original --type-mappings=DateTime=Date --type-mappings=object=any
  • Copy the .ts files into your projects ./src/services/you-api folder

Testing

For library unit testing we use Jest.

E2E Tests are located in this project.


Debugging with source-maps

If you have developed locally and when you update the library version in eehitus-ui project and start receiving errors, it's wise to generate local build using yarn cibuild:debug

This generates ./dist folder

Then go into eehitus-ui project

  • Remove .cache eehitus-ui/node_modules/.cache
  • Remove old dist eehitus-ui/node_modules/eehitus-*project_name*/dist
  • Copy your project local debug build dist folder to eehitus-ui/node_modules/eehitus-*project_name*
  • Start eehitus-ui using yarn start now the error should have source-maps and debugging it, should be easier.

Branching

For developing we use Git Flow branching pattern

Example branch names

  • release/project_name
  • fix/TICKET_NR-short-description
  • feature/TICKET_NR-short-description
  • company_name/feature/TICKET_NR-short-description

We don't recommend creating develop branch.

Good approach is to create a release/* branch and all new development in company_name/feature/* you create a Merge Request against release/*

You create tags on the release/* branch and you have a separate project namespace in rancher where you update eehitus-ui


Publishing

To get new version of the library up.

  1. Go to Gitlab
  2. Find your project and go to tags page document-ui as example
  3. Create a New tag, specify version in semver pattern version-*.*.* add a description of project tag or other description
  4. Update your projects eehitus-ui/package.json version and run yarn to generate new yarn.lock file and commit it
  5. Create a New tag for eehitus-ui
  6. Update the eehitus-ui in rancher project_namespace, you should never update the v1 ingress eehitus-ui. v1 represents master and should always be in stable state.

Old readme start


EHR related

thus the following libraries must also be present:

  • "ehr-components": "0.2.17"
  • "react-intl": "5.25.1"
  • "axios": "0.21.0"
  • "ehr-auth-react": "0.0.38"
  • "keycloak-js": "11.0.2"

Quickstart

All previous dependencies can be installed (e.g. on a fresh project) using yarn add react react-dom ehr-components react-intl axios ehr-auth-react keycloak-js, but check after installation correct versions in package.json file.

Installation

1. Install the ehr-3d-twin dependencie

yarn add ehr-3d-twin

2. Expose CESIUM_BASE_URL

The Easiest way (CDN)

Importing Cesium CDN into the head of the public/index.html

<script src="https://cesium.com/downloads/cesiumjs/releases/1.95/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.95/Build/Cesium/Widgets/widgets.css" rel="stylesheet">

Statically serve the cesium built files with custom bundler

  1. Copy cesium static files into /public
      node_modules/cesium/Build/Cesium/Workers
      node_modules/cesium/Build/Cesium/ThirdParty
      node_modules/cesium/Build/Cesium/Assets
      node_modules/cesium/Build/Cesium/Widgets
      node_modules/cesium/Build/Cesium/Cesium.js
  2. Configure the application bundler to serve these files
  3. Set the CESIUM_BASE_URL to point to the serving location (e.g.window.CESIUM_BASE_URL = '/';) This should be the first line of code
  4. Import cesium into the project
      import * as Cesium from 'cesium';
      import "cesium/Build/Cesium/Widgets/widgets.css";

More information on this method

Note: The mta styles should be also included for the application to look as expected.

on index.js

  import "../node_modules/ehr-components/build/static/css/mta_visuaal.css";

Typescript is fully supported.

Props

Required props should be passed on <Map3D />.

| Prop | Type | Description | Example | | ---- | ---- | ----------- | ------- | | config | Map3DProps | Sets the initial state of the component. The urls for the external services are required. | {base:{urls:{APP: 'https://livekluster.ehr.ee',APP_1: 'https://livekluster.ehr.ee',APP_2: 'https://livekluster.ehr.ee',APP_3: 'https://livekluster.ehr.ee',APP_4: 'https://livekluster.ehr.ee',APP_ENDING: '/',GEOPORTAL: 'http://localhost:3000/index.php',MAAMET: 'https://www.maaamet.ee/et',MAAMET_MAP: 'https://kaart.maaamet.ee',MAAMET_TILES: 'https://tiles.maaamet.ee',MAAMET_XGIS: 'https://xgis.maaamet.ee',MAAMET_KATASTER: 'https://ky.kataster.ee',KINNISTUSRAAMAT: 'https://kinnistusraamat.rik.ee',GSAVALIK: 'https://gsavalik.envir.ee',TALLINN: 'https://gis.tallinn.ee/veebikaart/',DOCUMENT_SERVICE_ENDPOINT: 'https://livekluster.ehr.ee/api/document/v1',CLASSIFIER_SERVICE_ENDPOINT: 'https://livekluster.ehr.ee/api/classifier/v1',PLANK: 'https://planeeringud.ee'}}|

Full list of supported initial configurations:

  config: {
    layers?: {
      layers2D?: {
        showAdministrationUnits?: {
          showing: boolean,
          transparency: 100,
        },
        showBridges?: {
          showing: boolean,
          transparency: 100,
        },
        showCadastres?: {
          showing: boolean,
          transparency: 100,
        },
        showGeology?: {
          showing: boolean,
          transparency: 100,
        },
        showKPO?: {
          showing: boolean,
          transparency: 100,
        },
        showKPOWater?: {
          showing: boolean,
          transparency: 100,
        },
        showKPOEnvironment?: {
          showing: boolean,
          transparency: 100,
        },
        showKPOTechno?: {
          showing: boolean,
          transparency: 100,
        },
        showKPOOther?: {
          showing: boolean,
          transparency: 100,
        },
        showRoads?: {
          showing: boolean,
          transparency: 100,
        },
        showTraps?: {
          showing: boolean,
          transparency: 100,
        },
        showTrafficRoads?: {
          showing: boolean,
          transparency: 100,
        },
        showNoiseWalls?: {
          showing: boolean,
          transparency: 100,
        },
        showBusStops?: {
          showing: boolean,
          transparency: 100,
        },
        showExits?: {
          showing: boolean,
          transparency: 100,
        },
        showCrossings?: {
          showing: boolean,
          transparency: 100,
        },
        showHydrants?: {
          showing: boolean,
          transparency: 100,
        },
        showWaterSources?: {
          showing: boolean,
          transparency: 100,
        },
        showTileSquares?: {
          showing: boolean,
          transparency: 100,
        },
      },
      layers3D?: {
        showAirzone?: {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showVegetation?: {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showRoadsETAK?: {
          showing: boolean,
        },
        showTerrain?: boolean,
        showLOD1?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showLOD2?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showLOD3?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showOldTown?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showFloodMap1?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showFloodMap10?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showFloodMap50?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showFloodMap100?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showFloodMap1000?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showRiskAreas?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showTrees?: boolean,
        showForests?: boolean,
        showUtilities?:  {
          transparency: 0 | 25 | 50 | 75 | 100,
          showing: boolean,
        },
        showColorHeights?: boolean,
        showColorByUsage?: boolean,
        showLabels?: boolean,
        showShadows?: boolean,
        excludedEhrCodes?: string[],
      },
    },
      functionalities?: {
        showDistanceMeasurement?: boolean,
        showMeasurement3D?: boolean,
        showDownloadBox?: boolean,
      },
      base: {
        showOnBoarding?: boolean,
        transparencyCanShow?: boolean,
        urls: {
          APP: string,
          APP_1: string,
          APP_2: string,
          APP_3: string,
          APP_4: string,
          APP_ENDING: string,
          GEOPORTAL: string,
          MAAMET: string,
          MAAMET_MAP: string,
          MAAMET_TILES: string,
          MAAMET_XGIS: string,
          MAAMET_KATASTER: string,
          KINNISTUSRAAMAT: string,
          GSAVALIK: string,
          TALLINN: string,
          PLANK: string,
		  DOCUMENT_SERVICE_ENDPOINT: string,
		  CLASSIFIER_SERVICE_ENDPOINT: string
        },
      },
      customBuildings?: {
        userFiles?: {
          files: EditableCustomFile[],
          filesProcessing: ToggleableAlert[],
          filesFailed: ToggleableAlert[],
          filesSucceeded: ToggleableAlert[],
        },
        sharedFiles?: CustomFile[],
        sharedCodes?: string[],
      },
      ui?: {
        layersPanelOpen?: boolean,
        basePanelOpen?: boolean,
        isLoading?: boolean,
        depthTest?: boolean,
      },
  }

  interface CustomFile {
    code: string,
    name: string,
    isVisible: boolean,
    urls: string[],
    ehrCode: string[],
  }

  interface EditableCustomFile extends CustomFile {
    isDeleting: boolean,
  }

  interface ToggleableAlert {
    code: string,
    errorCode: number,
    name: string,
    isVisible: boolean,
  }

Note: The value of these props should not be changed during runtime.

Props can be also passed (optionally) to the <Controls /> elements to set initial behaviour.

| Prop | Type | Description | Example | | ---- | ---- | ----------- | ------- | | coords | Cesium.Cartesian3 | undefined | The starting coordinates. | coords={new Cartesian3(3049660.4432725203, 1395285.2320070753, 5407747.336997399)} | | orientation | Cesium.HeadingPitchRoll | undefined | The starting orientation of the camera. | orientation={{ heading: 3.8891689628741344, pitch: -0.5010550170855081, roll: 6.280859574464753 }} | | ehrCode | string | undefined | The application will request for the bounding box of the ehr code from the search api and use this as the starting position. | ehrCode='120836089' | | cadastreCode | string | undefined | The application will request for the bounding box of the cadastre from the search api and use this as the starting position. | cadastreCode='78407:701:0267' | | config | ControlsConfig | undefined | Configuration object for showing the UI buttons, by default everything is shown. | config={{timeline: {visible: false,},layers: {visible: true,layers3D: {visible: true,AirzoneLayerButton: {visible: false,},},customBuildings: {visible: true,userBuildings: {visible: false,}}}}} |

Full list of controls config object

  {
  attribution?: {
    visible?: boolean,
  },
  baseLayerButton?: {
    visible?: boolean,
  },
  coordinatesInspector?: {
    visible?: boolean,
  },
  distanceMeasurementButton?: {
    visible?: boolean,
  },
  downloadButton?: {
    visible?: boolean,
  },
  fullscreenButton?: {
    visible?: boolean,
  },
  infoButton?: {
    visible?: boolean,
  },
  locationButton?: {
    visible?: boolean,
  },
  measurement3DButton?: {
    visible?: boolean,
  },
  search?: {
    visible?: boolean,
  },
  terrainTransparencyButton?: {
    visible?: boolean,
  },
  timeline?: {
    visible?: boolean,
  },
  zoomButtons?: {
    visible?: boolean,
  },
  layers?: {
    visible?: boolean,

      buildings?: {
      visible?: boolean,

      lod1Buildings?: boolean,
      lod2Buildings?: boolean,
      lod3Buildings?: boolean,
      oldTown?: boolean,
      utilities?: boolean,
      shadows?: boolean,
    },

    environment?: {
      visible?: boolean,

      vegetation?: boolean,
      cadastre?: boolean,
    },

    water?: {
      visible?: boolean,

      waterSources?: boolean,
      hydrants?: boolean,
    },

    roads?: {
      visible?: boolean,

      roads?: boolean,
      lightRoads?: boolean,
      busStops?: boolean,
      crossings?: boolean,
      exits?: boolean,
      bridges?: boolean,
      trups?: boolean,
      noiseWalls?: boolean,
    },

    areasAndRestrictions?: {
      visible?: boolean,

      airZones?: boolean,
      kpoWater?: boolean,
      kpoEnvironment?: boolean,
      kpoTechno?: boolean,
      kpoOther?: boolean,
      riskAreas?: boolean,
      floodMaps?: boolean,
    },

    information?: {
      visible?: boolean,

      geology?: boolean,
      tileSquares?: boolean,
      labels?: boolean,
    },

    customBuildings?: {
      visible?: boolean,

      sharedBuildings?: {
      visible?: boolean,
      },
      userBuildings?: {
        visible?: boolean,
      }
    },

    modellingTool?: {
      visible?: boolean,
    },

    thirdPartyLayers?: {
      visible?: boolean,
    }
  }
}

4. Troubleshooting

Text is not showing correctly (e.g. onBoarding.mouseLeft)

The library uses React Intl to configure the showing text. Inside the messages json that is used on IntlProvider put the corresponding keys with the translations. A json with all the keys (+ estonian translations) can be found in node_modules/ehr-3d-twin/etc/sample-intl.json

Invalid hook call. Hooks can only be called inside of the body of a function component.

Check the React and ReactDOM versions of ehr-components (e.g. npm ls react, npm ls react-dom). Make sure you are using those exact versions in your application (in the package.json) Add a resolution field (for all other libraries that use React and ReactDOM to follow)

  "resolutions": {
  "react": "18.2.0",
    "react-dom": "18.2.0"
  }

Error: Cannot find module 'eslint-visitor-keys

Add a resolution field

  "resolutions": {
  	"eslint": "7.28.0"
  },

Uncaught Error: [React Intl] Could not find required intl object. needs to exist in the component ancestry.

Check the ReactIntl version of ehr-component (e.g. npm ls react-intl`) Make sure you are using that exact version in your application (in the package.json) Add a resolution field

  "resolutions": {
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-intl": "5.25.1"
  },

index.js:1 Error constructing CesiumWidget. Visit http://get.webgl.org to verify that your web browser and hardware support WebGL.

The Cesium library is not imported correctly (see 2. Expose CESIUM_BASE_URL)

Application is not showing correctly / styles are missing

Mta styles are not included in the package, you can include them either on the index.html, on the index.js|ts(x), or on a sass file.

e.g. on a sass file

  @import "~ehr-components/build/static/css/mta_visuaal.css"

on index.js

  import "../node_modules/ehr-components/build/static/css/mta_visuaal.css";

Application is not responding

Make sure you are not using React.StrictMode