├── .husky ├── .gitignore └── pre-commit ├── .eslintignore ├── netlify.toml ├── src ├── react-app-env.d.ts ├── components │ ├── MapContainer │ │ ├── Map │ │ │ ├── index.tsx │ │ │ ├── MapContext.js │ │ │ ├── Map.css │ │ │ └── Map.tsx │ │ ├── orcapin.png │ │ ├── Layers │ │ │ ├── hydropin.png │ │ │ ├── index.tsx │ │ │ ├── Layers.tsx │ │ │ ├── TileLayer.tsx │ │ │ ├── VectorLayer.tsx │ │ │ └── googleSheets.tsx │ │ ├── Source │ │ │ ├── index.ts │ │ │ ├── osm.ts │ │ │ ├── xyz.ts │ │ │ └── vector.ts │ │ ├── Controls │ │ │ ├── index.tsx │ │ │ ├── Controls.tsx │ │ │ └── FullScreenControl.tsx │ │ ├── contain.css │ │ └── MapContainer.tsx │ ├── Map.tsx │ └── Marker.tsx ├── config │ └── config.js ├── setupTests.ts ├── views │ └── App.tsx ├── __tests__ │ └── App.test.tsx ├── index.tsx ├── index.css ├── assets │ └── logo.svg └── serviceWorker.ts ├── public ├── favicon.ico ├── logo192.png ├── logo512.png ├── robots.txt ├── manifest.json └── index.html ├── .prettierignore ├── tslint.eslint.json ├── .prettierrc ├── .vscode └── extensions.json ├── .env.example ├── .gitignore ├── tsconfig.json ├── .snyk ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── workflows │ ├── stageDeploy.yml │ ├── prodDeploy.yml │ ├── prDeploy.yml │ └── lint.yml └── PULL_REQUEST_TEMPLATE.md ├── .eslintrc.js ├── LICENSE ├── package.json ├── CONTRIBUTING.md ├── README.md └── data └── orcamap-test-data-2020-09-12.csv /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | src/ServiceWorker.ts 2 | /node_modules 3 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [[plugins]] 2 | package = "netlify-plugin-snyk" -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/components/MapContainer/Map/index.tsx: -------------------------------------------------------------------------------- 1 | export { default } from './Map' 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run lint 5 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orcasound/orcamap-react/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orcasound/orcamap-react/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orcasound/orcamap-react/HEAD/public/logo512.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | coverage/ 3 | dist/ 4 | build/ 5 | package-lock.json 6 | package.json 7 | docs/ -------------------------------------------------------------------------------- /tslint.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { "strict": true }, 3 | "include": ["**/src/**/*.ts", "**/test/**/*.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /src/components/MapContainer/orcapin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orcasound/orcamap-react/HEAD/src/components/MapContainer/orcapin.png -------------------------------------------------------------------------------- /src/components/MapContainer/Layers/hydropin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/orcasound/orcamap-react/HEAD/src/components/MapContainer/Layers/hydropin.png -------------------------------------------------------------------------------- /src/components/MapContainer/Source/index.ts: -------------------------------------------------------------------------------- 1 | import vector from './vector' 2 | import xyz from './xyz' 3 | import osm from './osm' 4 | 5 | export { vector, xyz, osm } 6 | -------------------------------------------------------------------------------- /src/components/MapContainer/Controls/index.tsx: -------------------------------------------------------------------------------- 1 | import Controls from './Controls' 2 | import FullScreenControl from './FullScreenControl' 3 | 4 | export { Controls, FullScreenControl } 5 | -------------------------------------------------------------------------------- /src/components/MapContainer/Source/osm.ts: -------------------------------------------------------------------------------- 1 | import * as olSource from 'ol/source' 2 | 3 | const osm = (): olSource.OSM => { 4 | return new olSource.OSM() 5 | } 6 | 7 | export default osm 8 | -------------------------------------------------------------------------------- /src/components/MapContainer/Map/MapContext.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | // eslint-disable-next-line new-cap 4 | const MapContext = new React.createContext() 5 | export default MapContext 6 | -------------------------------------------------------------------------------- /src/config/config.js: -------------------------------------------------------------------------------- 1 | const envKey = process.env['REACT_APP_GOOGLE_SHEETS_KEY'] || '' 2 | 3 | export default { 4 | apiKey: envKey, 5 | spreadsheetId: '1Xj9wk4vpiAcAk__5asRg2mpfJgIZNxvXsTPPuVTeoc4', 6 | } 7 | -------------------------------------------------------------------------------- /src/components/MapContainer/contain.css: -------------------------------------------------------------------------------- 1 | .setsides { 2 | display: flex; 3 | justify-content: center; 4 | } 5 | 6 | @media only screen and (max-width: 600px) { 7 | .setsides { 8 | margin: 1rem; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": false, 6 | "singleQuote": true, 7 | "trailingComma": "all", 8 | "bracketSpacing": true, 9 | "jsxBracketSameLine": false 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "formulahendry.auto-rename-tag", 6 | "mgmcdermott.vscode-language-babel", 7 | "VisualStudioExptTeam.vscodeintellicode" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /src/components/MapContainer/Layers/index.tsx: -------------------------------------------------------------------------------- 1 | import Layers from './Layers' 2 | import VectorLayer from './VectorLayer' 3 | import TileLayer from './TileLayer' 4 | import GoogleSheetsLayer from './googleSheets' 5 | 6 | export { Layers, VectorLayer, TileLayer, GoogleSheetsLayer } 7 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # hackathon login info. 2 | REACT_APP_DB_USER = example@example.com 3 | REACT_APP_DB_PASSWORD = changeME 4 | REACT_APP_SSEMMI_URL = https://CHANGME.example.org 5 | # endpoint example /api/apiv1/sightings - with token 6 | REACT_APP_GOOGLE_SHEETS_KEY = CHANGEMEDOYOUGETITGOOD -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect' 6 | -------------------------------------------------------------------------------- /src/components/MapContainer/Source/xyz.ts: -------------------------------------------------------------------------------- 1 | import * as olSource from 'ol/source' 2 | import { Options } from 'ol/source/XYZ' 3 | 4 | const xyz = ({ url, attributions, maxZoom }: Options): olSource.XYZ => { 5 | return new olSource.XYZ({ url, attributions, maxZoom }) 6 | } 7 | 8 | export default xyz 9 | -------------------------------------------------------------------------------- /src/components/MapContainer/Source/vector.ts: -------------------------------------------------------------------------------- 1 | import { Vector as VectorSource } from 'ol/source' 2 | import { Options } from 'ol/source/Vector' 3 | 4 | const vector = ({ features }: Options): VectorSource => { 5 | return new VectorSource({ 6 | features, 7 | }) 8 | } 9 | 10 | export default vector 11 | -------------------------------------------------------------------------------- /src/components/Map.tsx: -------------------------------------------------------------------------------- 1 | // import React from 'react'; 2 | import ReactMapboxGL from 'react-mapbox-gl' 3 | 4 | const Map = ReactMapboxGL({ 5 | // accessToken: 6 | accessToken: 7 | 'pk.eyJ1Ijoic3RvcmNrcGhvdG9zIiwiYSI6ImNrODNvYmc0czAxazMzbW1yZDdyeWZoNjAifQ.PiAIkQrVS4a5c7dBgcElhQ', 8 | }) 9 | 10 | export default Map 11 | -------------------------------------------------------------------------------- /src/components/MapContainer/Controls/Controls.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | interface Props { 4 | // eslint-disable-next-line 5 | children?: React.ReactNode 6 | } 7 | 8 | const Controls: React.FC = ({ children }: Props) => { 9 | return
{children}
10 | } 11 | 12 | export default Controls 13 | -------------------------------------------------------------------------------- /src/components/MapContainer/Layers/Layers.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | interface Children { 4 | // eslint-disable-next-line react/require-default-props 5 | children?: React.ReactNode 6 | } 7 | const Layers: React.FC = ({ children }: Children) => { 8 | return
{children}
9 | } 10 | 11 | export default Layers 12 | -------------------------------------------------------------------------------- /src/views/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import MapContainer from '../components/MapContainer/MapContainer' 4 | 5 | const App: React.FC = () => { 6 | return ( 7 |
8 |

(test OL) Orca Map

9 | 10 |
11 | ) 12 | } 13 | 14 | export default App 15 | -------------------------------------------------------------------------------- /src/__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from '@testing-library/react' 3 | import App from '../views/App' 4 | 5 | // TODO: window is not defined, Mapbox Needs it 6 | 7 | test('renders learn react link', () => { 8 | const { getByText } = render() 9 | const linkElement = getByText(/Orca Mapt/i) 10 | expect(linkElement).toBeInTheDocument() 11 | }) 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | # .vscode/ 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | .env 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | # Local Netlify folder 27 | .netlify -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import './index.css' 4 | import App from './views/App' 5 | import * as serviceWorker from './serviceWorker' 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | 12 | document.getElementById('root'), 13 | ) 14 | 15 | // If you want your app to work offline and load faster, you can change 16 | // unregister() to register() below. Note this comes with some pitfalls. 17 | // Learn more about service workers: https://bit.ly/CRA-PWA 18 | serviceWorker.unregister() 19 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::after, 3 | *::before { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: inherit; 7 | } 8 | 9 | li, 10 | a { 11 | text-decoration: none; 12 | } 13 | 14 | body { 15 | box-sizing: border-box; 16 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 17 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 18 | sans-serif; 19 | -webkit-font-smoothing: antialiased; 20 | -moz-osx-font-smoothing: grayscale; 21 | } 22 | 23 | code { 24 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 25 | monospace; 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["./src", ".eslintrc.js"] 20 | } 21 | -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.19.0 3 | # ignores vulnerabilities until expiry date; change duration by modifying expiry date 4 | ignore: 5 | SNYK-JS-EJS-1049328: 6 | - react-scripts > workbox-webpack-plugin > workbox-build > @surma/rollup-plugin-off-main-thread > ejs: 7 | reason: None given 8 | expires: '2021-04-09T15:57:28.573Z' 9 | SNYK-JS-GLOBPARENT-1016905: 10 | - react-scripts > webpack > watchpack > watchpack-chokidar2 > chokidar > glob-parent: 11 | reason: no patch available 12 | expires: '2021-04-09T15:57:28.573Z' 13 | patch: {} 14 | -------------------------------------------------------------------------------- /src/components/MapContainer/Controls/FullScreenControl.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useEffect } from 'react' 2 | import { FullScreen } from 'ol/control' 3 | import MapContext from '../Map/MapContext' 4 | 5 | const FullScreenControl: React.FC = () => { 6 | const { map } = useContext(MapContext) 7 | 8 | useEffect(() => { 9 | if (!map.controls) return 10 | 11 | const fullScreenControl = new FullScreen({}) 12 | 13 | map.controls.push(fullScreenControl) 14 | 15 | // eslint-disable-next-line consistent-return 16 | return () => map.controls.remove(fullScreenControl) 17 | }, [map]) 18 | 19 | return null 20 | } 21 | 22 | export default FullScreenControl 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | 12 | 13 | **Describe the solution you'd like** 14 | 15 | 16 | **Describe alternatives you've considered** 17 | 18 | 19 | **Additional context** 20 | 21 | -------------------------------------------------------------------------------- /src/components/MapContainer/Map/Map.css: -------------------------------------------------------------------------------- 1 | .ol-map { 2 | height: 80vh; 3 | width: 90vw; 4 | margin: 1rem 0; 5 | } 6 | 7 | .ol-map:hover { 8 | cursor: -webkit-grab; 9 | cursor: -moz-grab; 10 | cursor: grab; 11 | } 12 | 13 | .ol-map:active { 14 | cursor: -webkit-grabbing; 15 | cursor: -webkit-grabbing; 16 | cursor: grabbing; 17 | } 18 | 19 | .ol-control { 20 | position: absolute; 21 | background-color: rgba(15, 1, 210, 0.4); 22 | border-radius: 4px; 23 | margin: 1rem; 24 | } 25 | 26 | @media only screen and (max-width: 600px) { 27 | .ol-control { 28 | position: absolute; 29 | background-color: rgba(15, 1, 210, 0.4); 30 | border-radius: 4px; 31 | margin-right: 1.5rem; 32 | } 33 | } 34 | 35 | @media only screen and (max-width: 400px) { 36 | .ol-control { 37 | position: absolute; 38 | background-color: rgba(15, 1, 210, 0.4); 39 | border-radius: 4px; 40 | margin-right: 2.5rem; 41 | } 42 | } 43 | 44 | .ol-full-screen { 45 | top: 0.5rem; 46 | right: 0.5rem; 47 | } 48 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line 2 | module.exports = { 3 | root: true, 4 | extends: [ 5 | 'airbnb-typescript', 6 | 'airbnb/hooks', 7 | 'plugin:prettier/recommended', 8 | 'plugin:react/recommended', 9 | 'plugin:@typescript-eslint/recommended', 10 | ], 11 | plugins: ['react', '@typescript-eslint', 'prettier'], 12 | env: { 13 | browser: true, 14 | es6: true, 15 | jasmine: true, 16 | jest: true, 17 | node: true, 18 | }, 19 | globals: { 20 | Atomics: 'readonly', 21 | SharedArrayBuffer: 'readonly', 22 | }, 23 | parser: '@typescript-eslint/parser', 24 | parserOptions: { 25 | ecmaVersion: 2020, 26 | sourceType: 'module', 27 | ecmaFeatures: { 28 | jsx: true, 29 | }, 30 | project: './tsconfig.json', 31 | tsconfigRootDir: __dirname, 32 | }, 33 | settings: { 34 | react: { 35 | pragma: 'React', 36 | version: 'detect', 37 | }, 38 | }, 39 | rules: { 40 | '@typescript-eslint/dot-notation': 0, 41 | 'no-plusplus': 0, 42 | }, 43 | } 44 | -------------------------------------------------------------------------------- /src/components/MapContainer/Layers/TileLayer.tsx: -------------------------------------------------------------------------------- 1 | import { useContext, useEffect } from 'react' 2 | import OLTileLayer from 'ol/layer/Tile' 3 | import MapContext from '../Map/MapContext' 4 | import { osm } from '../Source' 5 | 6 | interface Props { 7 | zIndex: number 8 | } 9 | 10 | // generates actual map background. source can alternately be fed from above 11 | const TileLayer: React.FC = ({ zIndex = 0 }: Props) => { 12 | const { map } = useContext(MapContext) 13 | 14 | useEffect(() => { 15 | if (!map.addLayer) return 16 | 17 | const tileLayer = new OLTileLayer({ 18 | source: osm(), 19 | zIndex, 20 | }) 21 | 22 | // do not change unless map context is hoisted from MapContainer. 23 | // eslint-disable-next-line 24 | map && map.addLayer && map.addLayer(tileLayer) 25 | tileLayer.setZIndex(zIndex) 26 | 27 | // eslint-disable-next-line 28 | return () => { 29 | if (map) { 30 | map.removeLayer(tileLayer) 31 | } 32 | } 33 | }, [map, zIndex]) 34 | 35 | return null 36 | } 37 | 38 | export default TileLayer 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Orcasound 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | 13 | **To Reproduce** 14 | 21 | 22 | **Expected behavior** 23 | 24 | 25 | **Screenshots (If applicable)** 26 | 27 | 28 | **Desktop (please complete the following information):** 29 | - OS: 30 | - Browser 31 | - Version 32 | 33 | **Smartphone (please complete the following information):** 34 | - Device: 35 | - OS: 36 | - Browser 37 | - Version 38 | 39 | **Additional context** 40 | 41 | -------------------------------------------------------------------------------- /src/components/MapContainer/Map/Map.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState, useEffect } from 'react' 2 | import './Map.css' 3 | import * as ol from 'ol' 4 | import MapContext from './MapContext' 5 | 6 | interface Props { 7 | // eslint-disable-next-line 8 | children?: React.ReactNode 9 | zoom: number 10 | center: number[] 11 | } 12 | 13 | const Map: React.FC = ({ children, zoom, center }: Props) => { 14 | const mapRef = useRef() as React.MutableRefObject 15 | const [map, setMap] = useState({}) 16 | 17 | // on component mount, create map object, set map state, 18 | // pass map state into mapcontext for access in layers. 19 | useEffect(() => { 20 | const options = { 21 | view: new ol.View({ zoom, center }), 22 | layers: [], 23 | controls: [], 24 | overlays: [], 25 | } 26 | 27 | const mapObject = new ol.Map(options) 28 | mapObject.setTarget(mapRef.current) 29 | setMap(mapObject) 30 | 31 | return () => mapObject.setTarget(undefined) 32 | }, [zoom, center]) 33 | 34 | return ( 35 | 36 |
37 | {children} 38 |
39 |
40 | ) 41 | } 42 | 43 | export default Map 44 | -------------------------------------------------------------------------------- /.github/workflows/stageDeploy.yml: -------------------------------------------------------------------------------- 1 | name: Netlify Staging Deploy 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | netlify-stage-deploy: 9 | name: Netlify Development Deploy 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout Repository 13 | uses: actions/checkout@master 14 | 15 | - name: Setup Node v14 16 | uses: actions/setup-node@master 17 | with: 18 | node-version: '14.x' 19 | 20 | - name: Add Environment Variables 21 | run: | 22 | export REACT_APP_DB_USER=${{secrets.REACT_APP_DB_USER}} 23 | export REACT_APP_DB_PASSWORD=${{secrets.REACT_APP_DB_PASSWORD}} 24 | export REACT_APP_SSEMMI_URL=${{secrets.REACT_APP_SSEMMI_URL}} 25 | export REACT_APP_GOOGLE_SHEETS_KEY=${{secrets.REACT_APP_GOOGLE_SHEETS_KEY}} 26 | 27 | - name: Install Dependencies 28 | run: npm ci 29 | 30 | - name: Build React WebApp 31 | run: npm run build 32 | 33 | - name: Deploy to Netlify 34 | uses: nwtgck/actions-netlify@v1.1 35 | with: 36 | publish-dir: './build' 37 | github-token: ${{ secrets.GITHUB_TOKEN }} 38 | enable-pull-request-comment: false 39 | enable-commit-comment: false 40 | overwrites-pull-request-comment: false 41 | enable-commit-status: false 42 | deploy-message: Stage Deploy - ${{ github.event.pull_request.title }} 43 | alias: staging 44 | env: 45 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 46 | NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} 47 | -------------------------------------------------------------------------------- /.github/workflows/prodDeploy.yml: -------------------------------------------------------------------------------- 1 | name: Netlify Production Deploy 2 | 3 | on: 4 | release: 5 | types: [released] 6 | 7 | jobs: 8 | netlify-prod-deploy: 9 | name: Netlify Production Deploy 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout Repository 13 | uses: actions/checkout@master 14 | 15 | - name: Setup Node v14 16 | uses: actions/setup-node@master 17 | with: 18 | node-version: '14.x' 19 | 20 | - name: Add Environment Variables 21 | run: | 22 | export REACT_APP_DB_USER=${{secrets.REACT_APP_DB_USER}} 23 | export REACT_APP_DB_PASSWORD=${{secrets.REACT_APP_DB_PASSWORD}} 24 | export REACT_APP_SSEMMI_URL=${{secrets.REACT_APP_SSEMMI_URL}} 25 | export REACT_APP_GOOGLE_SHEETS_KEY=${{secrets.REACT_APP_GOOGLE_SHEETS_KEY}} 26 | 27 | - name: Install Dependencies 28 | run: npm ci 29 | 30 | - name: Build React WebApp 31 | run: npm run build 32 | 33 | - name: Deploy to Netlify 34 | uses: nwtgck/actions-netlify@v1.1 35 | with: 36 | publish-dir: './build' 37 | production-branch: main 38 | production-deploy: true 39 | github-token: ${{ secrets.GITHUB_TOKEN }} 40 | deploy-message: Production Deploy - ${{ github.event.release.name }} 41 | enable-pull-request-comment: false 42 | enable-commit-comment: false 43 | overwrites-pull-request-comment: false 44 | enable-commit-status: false 45 | 46 | env: 47 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 48 | NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} 49 | -------------------------------------------------------------------------------- /.github/workflows/prDeploy.yml: -------------------------------------------------------------------------------- 1 | name: Netlify PR Preview Deploy 2 | 3 | on: 4 | pull_request: 5 | types: [labeled] 6 | 7 | jobs: 8 | netlify-pr-preview: 9 | name: Netlify Development Deploy 10 | runs-on: ubuntu-latest 11 | if: contains(github.event.pull_request.labels.*.name, 'create-live-preview') 12 | steps: 13 | - name: Checkout Repository 14 | uses: actions/checkout@master 15 | 16 | - name: Setup Node v14 17 | uses: actions/setup-node@master 18 | with: 19 | node-version: '14.x' 20 | 21 | - name: Add Environment Variables 22 | run: | 23 | export REACT_APP_DB_USER=${{secrets.REACT_APP_DB_USER}} 24 | export REACT_APP_DB_PASSWORD=${{secrets.REACT_APP_DB_PASSWORD}} 25 | export REACT_APP_SSEMMI_URL=${{secrets.REACT_APP_SSEMMI_URL}} 26 | export REACT_APP_GOOGLE_SHEETS_KEY=${{secrets.REACT_APP_GOOGLE_SHEETS_KEY}} 27 | 28 | - name: Install Dependencies 29 | run: npm ci 30 | 31 | - name: Build React WebApp 32 | run: npm run build 33 | 34 | - name: Deploy to Netlify 35 | uses: nwtgck/actions-netlify@v1.1 36 | with: 37 | publish-dir: './build' 38 | github-token: ${{ secrets.GITHUB_TOKEN }} 39 | deploy-message: 'Preview Deploy from GitHub Actions' 40 | enable-pull-request-comment: true 41 | enable-commit-comment: false 42 | env: 43 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 44 | NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} 45 | 46 | - name: removelabel 47 | uses: buildsville/add-remove-label@v1 48 | with: 49 | token: ${{secrets.GITHUB_TOKEN}} 50 | label: create-live-preview 51 | type: remove 52 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/components/Marker.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | import React, { useEffect, useState } from 'react' 3 | 4 | import { Layer, Feature } from 'react-mapbox-gl' 5 | import { GoogleSpreadsheet } from 'google-spreadsheet' 6 | 7 | import config from '../config/config' 8 | 9 | const doc = new GoogleSpreadsheet(config.spreadsheetId) 10 | doc.useApiKey(config.apiKey) 11 | 12 | type COORDINATE = { 13 | lat: number 14 | long: number 15 | } 16 | 17 | type COORDINATES = COORDINATE[] 18 | 19 | const Marker: React.FC = () => { 20 | const [coordinates, setCoordinates] = useState([ 21 | { 22 | lat: 0, 23 | long: 0, 24 | }, 25 | ]) 26 | 27 | useEffect(() => { 28 | try { 29 | const loadSpreadsheet = async () => { 30 | await doc.loadInfo() 31 | const sheet = doc.sheetsByIndex[0] 32 | console.log(sheet.title) 33 | console.log(sheet.rowCount) 34 | 35 | // TODO: this currently returns a single row from a sheet with 2+ entries, so only one map point is returned from sheets. 36 | const rows = await sheet.getRows() 37 | console.log('rows', rows) 38 | 39 | console.log(rows[0].timestamp) 40 | const newCoordinates = [] 41 | for (let i = 0; rows[i] != null && i < sheet.rowCount; i++) { 42 | newCoordinates.push({ 43 | long: rows[i].longitude, 44 | lat: rows[i].latitude, 45 | }) 46 | } 47 | setCoordinates(newCoordinates) 48 | } 49 | 50 | loadSpreadsheet() 51 | } catch (error) { 52 | console.log(error) 53 | } 54 | }, []) 55 | 56 | return ( 57 | 58 | {coordinates && 59 | coordinates.map((row, index) => { 60 | // eslint-disable-next-line 61 | return 62 | })} 63 | 64 | ) 65 | } 66 | 67 | export default Marker 68 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Pull request checklist 2 | 3 | Please check if your PR :rocket: fulfills the following requirements: 4 | 5 | - [ ] Tests for the changes have been added (for bug fixes / features) 6 | - [ ] Docs have been reviewed and added / updated if needed (for bug fixes / features) 7 | - [ ] Build (`npm run start`) was run locally and new changes were working correctly 8 | - [ ] Lint (`npm run linter`) has passed locally and any fixes were made for failures 9 | 10 | ## Pull request type 11 | 12 | 13 | 14 | Please check the type of change your PR introduces: 15 | 16 | - [ ] Bugfix 17 | - [ ] Feature 18 | - [ ] Code style update (formatting, renaming) 19 | - [ ] Refactoring (no functional changes, no api changes) 20 | - [ ] Build related changes 21 | - [ ] Documentation content changes 22 | - [ ] Other (please describe): 23 | 24 | ## What is the current behavior? 25 | 26 | 27 | 28 | Fixes # 29 | 30 | 31 | 32 | ## What is the new behavior? 33 | 34 | 35 | 36 | - 37 | - 38 | - 39 | 40 | ## Does this introduce a breaking change? 41 | 42 | - [ ] Yes 43 | - [ ] No 44 | 45 | 46 | 47 | **Checklist_User's_Behalf**: 48 | 49 | 50 | 51 | 52 | 53 | - [ ] Documentation 54 | - [ ] Tests 55 | - [ ] TypeScript Types 56 | - [ ] Ready to be merged 57 | 58 | 59 | ## Other information 60 | 61 | 62 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint Check 2 | 3 | on: 4 | pull_request: 5 | types: [labeled] 6 | 7 | jobs: 8 | eslint: 9 | name: ESLint Check 10 | runs-on: ubuntu-latest 11 | if: contains(github.event.pull_request.labels.*.name, 'lint-check') 12 | steps: 13 | - name: Checkout Repository 14 | uses: actions/checkout@v2 15 | 16 | - name: Setup Node.js 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: '14' 20 | 21 | - name: Install Dependencies 22 | run: cp ./package.json ./ && npm ci 23 | 24 | - name: Run ESLint 25 | uses: reviewdog/action-eslint@v1 26 | with: 27 | reporter: github-check 28 | github_token: ${{ secrets.GITHUB_TOKEN }} 29 | 30 | prettier: 31 | name: Prettier Check 32 | runs-on: ubuntu-latest 33 | if: contains(github.event.pull_request.labels.*.name, 'lint-check') 34 | steps: 35 | - name: Checkout Repository 36 | uses: actions/checkout@v2 37 | 38 | - name: Setup Node.js 39 | uses: actions/setup-node@v1 40 | with: 41 | node-version: '14' 42 | 43 | - name: Install Dependencies 44 | run: cp ./package.json ./ && npm ci 45 | 46 | - name: Run Prettier 47 | id: prettier_run 48 | run: | 49 | echo "::set-output name=prettier_output::$(npx prettier --list-different .)" 50 | echo "$(npx prettier --list-different . > prettier.txt)" 51 | 52 | - name: Comment on PR 53 | if: contains(${{ steps.prettier_run.outputs.prettier_output }}, '.'); 54 | uses: actions/github-script@v3 55 | with: 56 | github-token: ${{secrets.GITHUB_TOKEN}} 57 | script: | 58 | const fs = require('fs') 59 | const cmdoutput = fs.readFileSync(`${process.env.GITHUB_WORKSPACE}/prettier.txt`) 60 | console.log(cmdoutput) 61 | github.issues.createComment({ 62 | issue_number: context.issue.number, 63 | owner: context.repo.owner, 64 | repo: context.repo.repo, 65 | body: `Prettier Response:\n ${cmdoutput}` 66 | }) 67 | -------------------------------------------------------------------------------- /src/components/MapContainer/Layers/VectorLayer.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useEffect } from 'react' 2 | import OLVectorLayer from 'ol/layer/Vector' 3 | import GeoJSON from 'ol/format/GeoJSON' 4 | import { get } from 'ol/proj' 5 | 6 | // note: both the VectorLayer styleOptions object 7 | // and the 'source' from line 33 will need to be hoisted 8 | // to be able to make multiple different vector layers 9 | // for different data sources. 10 | import { Style, Icon } from 'ol/style' 11 | import hydropin from './hydropin.png' 12 | 13 | import MapContext from '../Map/MapContext' 14 | import { vector } from '../Source' 15 | 16 | const styleOptions = { 17 | MultiPointIcon: new Style({ 18 | image: new Icon({ 19 | src: hydropin, 20 | scale: [0.25, 0.25], 21 | }), 22 | }), 23 | } 24 | 25 | interface Props { 26 | coordinates: number[][] 27 | zIndex: number 28 | } 29 | 30 | const VectorLayer: React.FC = ({ coordinates, zIndex = 0 }: Props) => { 31 | const { map } = useContext(MapContext) 32 | 33 | useEffect(() => { 34 | if (!map.addLayer) return 35 | 36 | const vectorLayer = new OLVectorLayer({ 37 | source: vector({ 38 | features: new GeoJSON().readFeatures( 39 | { 40 | type: 'FeatureCollection', 41 | features: [ 42 | { 43 | type: 'Feature', 44 | properties: { 45 | kind: 'Sighting', 46 | name: 'SRKW', 47 | state: 'WA', 48 | }, 49 | geometry: { 50 | type: 'MultiPoint', 51 | coordinates, 52 | }, 53 | }, 54 | ], 55 | }, 56 | { 57 | featureProjection: get('EPSG:3857'), 58 | }, 59 | ), 60 | }), 61 | style: styleOptions.MultiPointIcon, 62 | }) 63 | 64 | map.addLayer(vectorLayer) 65 | vectorLayer.setZIndex(zIndex) 66 | 67 | // eslint-disable-next-line 68 | return () => { 69 | if (map) { 70 | map.removeLayer(vectorLayer) 71 | } 72 | } 73 | }, [map, coordinates, zIndex]) 74 | 75 | return null 76 | } 77 | 78 | export default VectorLayer 79 | -------------------------------------------------------------------------------- /src/components/MapContainer/Layers/googleSheets.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useEffect } from 'react' 2 | import OLVectorLayer from 'ol/layer/Vector' 3 | import GeoJSON from 'ol/format/GeoJSON' 4 | import { get } from 'ol/proj' 5 | import { Icon, Style } from 'ol/style' 6 | import hydropin from './hydropin.png' 7 | 8 | // note: both the VectorLayer styleOptions object 9 | // and the 'source' from line 33 will need to be hoisted 10 | // to be able to make multiple different vector layers 11 | // for different data sources. 12 | 13 | import { vector } from '../Source' 14 | import MapContext from '../Map/MapContext' 15 | 16 | const styleOptions = { 17 | MultiPointIcon: new Style({ 18 | image: new Icon({ 19 | src: hydropin, 20 | scale: [0.25, 0.25], 21 | }), 22 | }), 23 | } 24 | 25 | interface Props { 26 | coordinates: number[][] 27 | zIndex: number 28 | } 29 | 30 | const GoogleSheetsLayer: React.FC = ({ 31 | coordinates, 32 | zIndex = 0, 33 | }: Props) => { 34 | const { map } = useContext(MapContext) 35 | 36 | useEffect(() => { 37 | if (!map.addLayer) return 38 | 39 | const vectorLayer = new OLVectorLayer({ 40 | source: vector({ 41 | features: new GeoJSON().readFeatures( 42 | { 43 | type: 'FeatureCollection', 44 | features: [ 45 | { 46 | type: 'Feature', 47 | properties: { 48 | kind: 'Sighting', 49 | name: 'SRKW', 50 | state: 'WA', 51 | }, 52 | geometry: { 53 | type: 'MultiPoint', 54 | coordinates, 55 | }, 56 | }, 57 | ], 58 | }, 59 | { 60 | featureProjection: get('EPSG:3857'), 61 | }, 62 | ), 63 | }), 64 | style: styleOptions.MultiPointIcon, 65 | }) 66 | 67 | map.addLayer(vectorLayer) 68 | vectorLayer.setZIndex(zIndex) 69 | 70 | // eslint-disable-next-line 71 | return () => { 72 | if (map) { 73 | map.removeLayer(vectorLayer) 74 | } 75 | } 76 | }, [map, coordinates, zIndex]) 77 | 78 | return null 79 | } 80 | 81 | export default GoogleSheetsLayer 82 | -------------------------------------------------------------------------------- /src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "orcamap-react", 3 | "description": "ReactJS version of Orcamap, an open-source bioacoustic tools aimed at saving endangered orcas.", 4 | "version": "0.1.0", 5 | "private": true, 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/orcasound/orcamap-react.git" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/orcasound/orcamap-react/issues" 12 | }, 13 | "main": "src/index.js", 14 | "keywords": [ 15 | "react", 16 | "create-react-app", 17 | "typescript", 18 | "material-ui", 19 | "orcamap", 20 | "orcamap-reactjs", 21 | "orca", 22 | "bioacoustic-tools" 23 | ], 24 | "dependencies": { 25 | "@testing-library/jest-dom": "^5.11.9", 26 | "@testing-library/react": "^11.2.5", 27 | "@testing-library/user-event": "^12.8.3", 28 | "@types/jest": "^26.0.20", 29 | "@types/node": "^14.14.33", 30 | "@types/openlayers": "^4.6.17", 31 | "@types/react": "^17.0.3", 32 | "@types/react-dom": "^17.0.2", 33 | "chokidar": "^3.5.1", 34 | "dotenv": "^8.2.0", 35 | "google-spreadsheet": "^3.1.15", 36 | "mapbox-gl": "^1.13.0", 37 | "ol": "^6.5.0", 38 | "rbush": "^3.0.1", 39 | "react": "^17.0.1", 40 | "react-dom": "^17.0.1", 41 | "react-mapbox-gl": "^5.1.1", 42 | "react-scripts": "^4.0.3", 43 | "typescript": "^4.2.3" 44 | }, 45 | "scripts": { 46 | "start": "react-scripts start", 47 | "build": "react-scripts build", 48 | "test": "react-scripts test", 49 | "eject": "react-scripts eject", 50 | "lint": "tsc --noEmit && eslint src/", 51 | "lint:fix": "tsc --noEmit && eslint src/ --fix", 52 | "prepare": "husky install", 53 | "commit": "cz", 54 | "format": "prettier --write ." 55 | }, 56 | "browserslist": { 57 | "production": [ 58 | ">0.2%", 59 | "not dead", 60 | "not op_mini all" 61 | ], 62 | "development": [ 63 | "last 1 chrome version", 64 | "last 1 firefox version", 65 | "last 1 safari version" 66 | ] 67 | }, 68 | "devDependencies": { 69 | "@types/google-spreadsheet": "^3.0.2", 70 | "@types/mapbox-gl": "^1.12.8", 71 | "@types/ol": "^6.4.2", 72 | "@typescript-eslint/eslint-plugin": "^4.16.1", 73 | "@typescript-eslint/parser": "^4.16.1", 74 | "cz-conventional-changelog": "^3.3.0", 75 | "eslint": "^7.21.0", 76 | "eslint-config": "^0.3.0", 77 | "eslint-config-airbnb": "^18.2.1", 78 | "eslint-config-airbnb-typescript": "^12.3.1", 79 | "eslint-config-prettier": "^8.1.0", 80 | "eslint-plugin-import": "^2.22.1", 81 | "eslint-plugin-jsx-a11y": "^6.4.1", 82 | "eslint-plugin-prettier": "^3.3.1", 83 | "eslint-plugin-react": "^7.22.0", 84 | "eslint-plugin-react-hooks": "^4.2.0", 85 | "husky": "^5.1.3", 86 | "lint-staged": "^10.5.4", 87 | "netlify-plugin-snyk": "^1.3.0", 88 | "prettier": "^2.2.1" 89 | }, 90 | "lint-staged": { 91 | "*.{js,ts,tsx}": [ 92 | "npm run lint:fix" 93 | ] 94 | }, 95 | "config": { 96 | "commitizen": { 97 | "path": "./node_modules/cz-conventional-changelog" 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | [![Netlify Status](https://api.netlify.com/api/v1/badges/1cd65f8d-b1c3-4046-8a77-089fd57d0aec/deploy-status)](https://app.netlify.com/sites/orcamap/deploys) 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | ## How to contribute to OrcaMap 6 | 7 | 8 | #### **Do you intend to add a new feature or change an existing one?** 9 | 10 | * Awesome! Suggest your change in the [Issues](https://github.com/orcasound/orcamap-react/issues) 11 | 12 | ### **Are you a Google Summer of Code Student?** 13 | 14 | * Great! Please review https://github.com/orcasound/orcagsoc/issues and our repo's [Issues](https://github.com/orcasound/orcamap-react/issues) 15 | * On Slack, prefer group communication. Please do not DM Ivan or project leads directly, post questions and ideas in [#orcamap-react](https://orcasound.slack.com/archives/C010J5ENUMN) so that the group is aware of movement on the project 16 | 17 | ### **Before coding:** 18 | - Please make sure you review the [#orcamap-react](https://orcasound.slack.com/archives/C010J5ENUMN) channel history 19 | - Post what you would like to work on in the channel and Github issues and make sure others are not already working on it 20 | - Post in the [#orcamap-react](https://orcasound.slack.com/archives/C010J5ENUMN) channel when you have begun work 21 | - Your branch name and commit messages should follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) standards - no generic names like 'dev'. Use `npm run commit` to use [commitizen](http://commitizen.github.io/cz-cli/) to help name commits 22 | - Your PR should show up in [#orcamap-react](https://orcasound.slack.com/archives/C010J5ENUMN) automatically from the Github bot 23 | 24 | 25 | *It's all about clear and detailed communication in the group.* This is a self-organizing group, so communication is key. 26 | ### **Good PR's solve one thing** 27 | 28 | * Instead of thinking of a PR as "here's all the work I did today" Please limit your PR to one topic or unit of code. This makes PRs smaller, easier to review, and easier to merge 29 | * Tag other contributors for review on your PR 30 | * Include tests if possible 31 | 32 | #### **Did you find a bug?** 33 | 34 | * **Do not open up a GitHub issue if the bug is a security vulnerability 35 | in Orcamap**, and instead to refer to our [security policy](https://orcasound.org/security/). 36 | 37 | * **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/orcasound/orcamap-react/issues). 38 | 39 | * If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/orcasound/orcamap-react/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. 40 | 41 | #### **Did you write a patch that fixes a bug?** 42 | 43 | * Open a new GitHub pull request with the patch. 44 | 45 | * Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. 46 | 47 | 48 | 49 | 50 | 51 | Orcasound and Orcamap are a volunteer effort. We encourage you to pitch in and join [the team](https://www.orcasound.net/support/#hack)! 52 | 53 | Thanks! :heart: :heart: :heart: 54 | 55 | Orcamap Team -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Orcamap ReactJS 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/1cd65f8d-b1c3-4046-8a77-089fd57d0aec/deploy-status)](https://app.netlify.com/sites/orcamap/deploys) 4 | 5 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 6 | 7 | This project aims to organize and update the [Orcamap code](https://github.com/orcasound/orcamap). The `orcamap` code implemented a 2019 prototype for mapping sounds heard through the [Orcasound hydrophone network](orcasound.net). It exchanged data with a Google spreadsheet and used Mapbox before they changed pricing model and close sourced some of their code. 8 | 9 | Orcamap-react is a work in progress (2021-22+). This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). A test deployment via [Netlify](https://netlify.com) was accomplished at [https://orcamap.netlify.app/](https://orcamap.netlify.app/) in mid-2021. 10 | 11 | ## Setup 12 | 13 | 1. Clone the repo. 14 | 15 | ## Prerequistes 16 | 17 | - Install [NodeJS](https://nodejs.org/en/download/package-manager/) on your development machine 18 | - Request access to Google Spreadsheets data source 19 | 20 | ## Run 21 | 22 | 1. Execute `npm install` . 23 | 2. Execute `npm start` . 24 | 25 | ## Environment 26 | 27 | This project uses typescript version 4.1.2, please make sure your code editor is using this version (vscode uses 4.0.3 from its own node modules by default.) 28 | [see this stack overflow](https://stackoverflow.com/questions/39668731/what-typescript-version-is-visual-studio-code-using-how-to-update-it) 29 | 30 | ## Available Scripts 31 | 32 | In the project directory, you can run: 33 | 34 | ### `npm start` 35 | 36 | Runs the app in the development mode.
37 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 38 | 39 | The page will reload if you make edits.
40 | You will also see any lint errors in the console. 41 | 42 | ### `npm test` 43 | 44 | Launches the test runner in the interactive watch mode.
45 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 46 | 47 | ### `npm run build` 48 | 49 | Builds the app for production to the `build` folder.
50 | It correctly bundles React in production mode and optimizes the build for the best performance. 51 | 52 | The build is minified and the filenames include the hashes.
53 | Your app is ready to be deployed! 54 | 55 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 56 | 57 | ### `npm run eject` 58 | 59 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 60 | 61 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 62 | 63 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 64 | 65 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 66 | 67 | ## Learn More 68 | 69 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 70 | 71 | To learn React, check out the [React documentation](https://reactjs.org/). 72 | -------------------------------------------------------------------------------- /src/components/MapContainer/MapContainer.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react' 2 | import { fromLonLat } from 'ol/proj' 3 | import { GoogleSpreadsheet } from 'google-spreadsheet' 4 | import Map from './Map' 5 | import './contain.css' 6 | import config from '../../config/config' 7 | import { Layers, TileLayer, VectorLayer, GoogleSheetsLayer } from './Layers' 8 | import { Controls, FullScreenControl } from './Controls' 9 | import orca from './orcapin.png' 10 | 11 | const doc = new GoogleSpreadsheet(config.spreadsheetId) 12 | doc.useApiKey(config.apiKey) 13 | 14 | const MapContainer: React.FC = () => { 15 | const [coordinates, setCoordinates] = useState([[0, 0]]) 16 | const [googleSheetcoordinates, setgoogleSheetcoordinates] = useState([[0, 0]]) 17 | const [zoom, setZoom] = useState(0) 18 | const [center, setCenter] = useState([0, 0]) 19 | const [showLayer, setShowLayer] = useState(true) 20 | 21 | useEffect(function effectFunction() { 22 | async function loadSpreadsheet() { 23 | try { 24 | await doc.loadInfo() 25 | const sheet = doc.sheetsByIndex[0] 26 | 27 | setCoordinates([ 28 | [-122.76045, 48.13569], // Port Townsend 29 | [-122.6039, 48.03371], // Bush Point 30 | [-123.17357, 48.55833], // Orcasound Lab 31 | // [-122.4544, 47.3365], 32 | // [-122.4768, 47.7365], 33 | // [-122.4108, 47.7365], 34 | ]) 35 | setZoom(9) 36 | setCenter([-122.4713, 47.7237]) 37 | 38 | // TODO: this currently returns a single row from a sheet with 2+ entries, so only one map point is returned from sheets. 39 | const rows = await sheet.getRows() 40 | 41 | for (let i = 0; rows[i] != null && i < sheet.rowCount; i++) { 42 | setgoogleSheetcoordinates((coordinatesheet) => [ 43 | ...coordinatesheet, 44 | [rows[i].longitude, rows[i].latitude], 45 | ]) 46 | } 47 | } catch (err) { 48 | // eslint-disable-next-line 49 | console.log(err) 50 | } 51 | } 52 | loadSpreadsheet() 53 | }, []) 54 | 55 | return ( 56 | <> 57 |
58 | possible orca pin 59 | setShowLayer(event.target.checked)} 63 | />{' '} 64 | Pod Sightings 65 |
66 | 67 |

74 | Test map of test coordinates 75 |

76 | 77 |
78 | 79 | 80 | 81 | {showLayer && } 82 | 83 | 84 | 85 | 86 | 87 | 88 |
89 | 90 |

97 | Google Sheets Coordinates 98 |

99 | 100 |
101 | 102 | 103 | 104 | {showLayer && ( 105 | 109 | )} 110 | 111 | 112 | 113 | 114 | 115 | 116 |
117 | 118 | ) 119 | } 120 | 121 | export default MapContainer 122 | -------------------------------------------------------------------------------- /src/serviceWorker.ts: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.0/8 are considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/, 20 | ), 21 | ) 22 | 23 | type Config = { 24 | onSuccess?: (registration: ServiceWorkerRegistration) => void 25 | onUpdate?: (registration: ServiceWorkerRegistration) => void 26 | } 27 | 28 | export function register(config?: Config) { 29 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 30 | // The URL constructor is available in all browsers that support SW. 31 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href) 32 | if (publicUrl.origin !== window.location.origin) { 33 | // Our service worker won't work if PUBLIC_URL is on a different origin 34 | // from what our page is served on. This might happen if a CDN is used to 35 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 36 | return 37 | } 38 | 39 | window.addEventListener('load', () => { 40 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js` 41 | 42 | if (isLocalhost) { 43 | // This is running on localhost. Let's check if a service worker still exists or not. 44 | // eslint-disable-next-line 45 | checkValidServiceWorker(swUrl, config) 46 | 47 | // Add some additional logging to localhost, pointing developers to the 48 | // service worker/PWA documentation. 49 | navigator.serviceWorker.ready.then(() => { 50 | console.log( 51 | 'This web app is being served cache-first by a service ' + 52 | 'worker. To learn more, visit https://bit.ly/CRA-PWA', 53 | ) 54 | }) 55 | } else { 56 | // Is not localhost. Just register service worker 57 | // eslint-disable-next-line 58 | registerValidSW(swUrl, config) 59 | } 60 | }) 61 | } 62 | } 63 | 64 | function registerValidSW(swUrl: string, config?: Config) { 65 | navigator.serviceWorker 66 | .register(swUrl) 67 | .then((registration) => { 68 | registration.onupdatefound = () => { 69 | const installingWorker = registration.installing 70 | if (installingWorker == null) { 71 | return 72 | } 73 | installingWorker.onstatechange = () => { 74 | if (installingWorker.state === 'installed') { 75 | if (navigator.serviceWorker.controller) { 76 | // At this point, the updated precached content has been fetched, 77 | // but the previous service worker will still serve the older 78 | // content until all client tabs are closed. 79 | console.log( 80 | 'New content is available and will be used when all ' + 81 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.', 82 | ) 83 | 84 | // Execute callback 85 | if (config && config.onUpdate) { 86 | config.onUpdate(registration) 87 | } 88 | } else { 89 | // At this point, everything has been precached. 90 | // It's the perfect time to display a 91 | // "Content is cached for offline use." message. 92 | console.log('Content is cached for offline use.') 93 | 94 | // Execute callback 95 | if (config && config.onSuccess) { 96 | config.onSuccess(registration) 97 | } 98 | } 99 | } 100 | } 101 | } 102 | }) 103 | .catch((error) => { 104 | console.error('Error during service worker registration:', error) 105 | }) 106 | } 107 | 108 | function checkValidServiceWorker(swUrl: string, config?: Config) { 109 | // Check if the service worker can be found. If it can't reload the page. 110 | fetch(swUrl, { 111 | headers: { 'Service-Worker': 'script' }, 112 | }) 113 | .then((response) => { 114 | // Ensure service worker exists, and that we really are getting a JS file. 115 | const contentType = response.headers.get('content-type') 116 | if ( 117 | response.status === 404 || 118 | (contentType != null && contentType.indexOf('javascript') === -1) 119 | ) { 120 | // No service worker found. Probably a different app. Reload the page. 121 | navigator.serviceWorker.ready.then((registration) => { 122 | registration.unregister().then(() => { 123 | window.location.reload() 124 | }) 125 | }) 126 | } else { 127 | // Service worker found. Proceed as normal. 128 | registerValidSW(swUrl, config) 129 | } 130 | }) 131 | .catch(() => { 132 | console.log( 133 | 'No internet connection found. App is running in offline mode.', 134 | ) 135 | }) 136 | } 137 | 138 | export function unregister() { 139 | if ('serviceWorker' in navigator) { 140 | navigator.serviceWorker.ready 141 | .then((registration) => { 142 | registration.unregister() 143 | }) 144 | .catch((error) => { 145 | console.error(error.message) 146 | }) 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /data/orcamap-test-data-2020-09-12.csv: -------------------------------------------------------------------------------- 1 | timestamp,humantime,type,user,observation time,longitude,latitude,verified?,Notes,Source,Species,Pod,Sub-pod,Individuals,Unique track?,Newsletter? ('yes' to include),Narrative (for newsletter),Photo link,Photo credit,Link,Reported direction?,Computed direction,Computed speed 2 | 1535745799493,2018-08-31T20:03:19.493Z,visual,sveirs@gmail.com,2018-05-17T17:00:00.00-07:00,-126.3580603,49.27906887,yes,"~30 orcas; All of J pod, and members of K and L. Maybe super-pod?",,,J; K+L?,,,,,,,,,,, 3 | 1535745986418,2018-08-31T20:06:26.418Z,visual,sveirs@gmail.com,2018-05-17T19:13:00.00-07:00,-126.5438686,49.37723003,yes,See May 17 notes at http://www.orcanetwork.org/Archives/index.php?categories_file=Sightings%20Archive%20-%20May%2018,,,J; K+L?,,,,,,,,,,, 4 | 1535751126000,2018-08-31T21:32:06.000Z,visual,sveirs@gmail.com,2018-06-11T09:00:00.00-07:00,-123.1566236,48.51495983,yes,"Acoustic detection at Lime Kiln by Alisa: echolocation and ""chatter about residents in Haro...""",,,SRKW?,,,,,,,,,,, 5 | 1535752465544,2018-08-31T21:54:25.544Z,visual,sveirs@gmail.com,2018-06-11T10:00:00.00-07:00,-123.1792494,48.53845275,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 6 | 1535752468154,2018-08-31T21:54:28.154Z,visual,sveirs@gmail.com,2018-06-11T11:00:00.00-07:00,-123.1929181,48.56355382,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 7 | 1535752367909,2018-08-31T21:52:47.909Z,visual,sveirs@gmail.com,2018-06-11T12:00:00.00-07:00,-123.2021776,48.58368405,yes,"Time uncertain (between 10 and 16:42?), but multiple accounts say L12s turned southbound at Henry Is.",,,L,L-12s,,,,,,,,,, 8 | 1535752470668,2018-08-31T21:54:30.668Z,visual,sveirs@gmail.com,2018-06-11T12:00:00.00-07:01,-123.2065868,48.58397574,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 9 | 1535752479210,2018-08-31T21:54:39.210Z,visual,sveirs@gmail.com,2018-06-11T13:00:00.00-07:01,-123.230347,48.63475273,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 10 | 1535752480727,2018-08-31T21:54:40.727Z,visual,sveirs@gmail.com,2018-06-11T14:00:00.00-07:01,-123.2563743,48.69014558,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 11 | 1535752482174,2018-08-31T21:54:42.174Z,visual,sveirs@gmail.com,2018-06-11T15:00:00.00-07:02,-123.2814377,48.73721344,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 12 | 1535752486281,2018-08-31T21:54:46.281Z,visual,sveirs@gmail.com,2018-06-11T16:00:00.00-07:02,-123.3354203,48.78804808,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 13 | 1535751415219,2018-08-31T21:36:55.219Z,visual,sveirs@gmail.com,2018-06-11T16:42:00.00-07:00,-123.1528829,48.51248183,yes,Passing LK wall southbound (Cindy Hansen),,,L,L-12s,,,,,,,,,, 14 | 1535752488328,2018-08-31T21:54:48.328Z,visual,sveirs@gmail.com,2018-06-11T17:00:00.00-07:02,-123.3508439,48.86039856,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 15 | 1535751428863,2018-08-31T21:37:08.863Z,visual,sveirs@gmail.com,2018-06-11T17:08:00.00-07:00,-123.1459586,48.5048889,yes,Leaders southbound at West side preserve (Cindy Hansen),,,L,L-12s,,,,,,,,,, 16 | 1535752490944,2018-08-31T21:54:50.944Z,visual,sveirs@gmail.com,2018-06-11T18:00:00.00-07:03,-123.2640861,48.92251111,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 17 | 1535751431553,2018-08-31T21:37:11.553Z,visual,sveirs@gmail.com,2018-06-11T18:25:00.00-07:00,-123.1295631,48.49202051,yes,Hannah Heights southbound (Cindy),,,L,L-12s,,,,,,,,,, 18 | 1535752492914,2018-08-31T21:54:52.914Z,visual,sveirs@gmail.com,2018-06-11T19:00:00.00-07:03,-123.2255271,48.98834208,yes,Interpolated based on David Howitt's account of his day w/them...,,,J+Ls-L12s,,,,,,,,,,, 19 | 1535752037897,2018-08-31T21:47:17.897Z,visual,sveirs@gmail.com,2018-06-11T19:40:00.00-07:00,-123.008746,48.42646766,yes,L-12s off of South Beach (Alisa),,,L,L-12s,,,,,,,,,, 20 | 1535752027748,2018-08-31T21:47:07.748Z,visual,sveirs@gmail.com,2018-06-11T20:10:00.00-07:00,-123.0319862,48.44864477,yes,Drifting further south and offshore (Alisa),,,L,L-12s,,,,,,,,,, 21 | 1535760801498,2018-09-01T00:13:21.498Z,visual,sveirs@gmail.com,2018-06-12T09:52:00.00-07:00,-123.0053206,48.67123199,yes,southbound in President's channel (Monika),,,L,"L4s, L26s, L47s, L72s went Spieden",,1,,,,,,,, 22 | 1535760918610,2018-09-01T00:15:18.610Z,visual,sveirs@gmail.com,2018-06-12T10:45:00.00-07:00,-123.0485866,48.63762225,yes,"heading south, or west? (Alisa)",,,L,"L4s, L26s, L47s, L72s went Spieden",,1,,,,,,,, 23 | 1535761446908,2018-09-01T00:24:06.908Z,visual,sveirs@gmail.com,2018-06-12T11:10:00.00-07:00,-123.1305783,48.62867769,yes,heading west in Speiden (Monika),,,L,"L4s, L26s, L47s, L72s went Spieden",,1,,,,,,,, 24 | 1535761915104,2018-09-01T00:31:55.104Z,visual,sveirs@gmail.com,2018-06-12T12:00:00.00-07:00,-123.780437,48.33329107,yes,L12s westbound at Sooke (time unspecified),,,L,L12s,,,,,,,,,, 25 | 1535761720464,2018-09-01T00:28:40.464Z,visual,sveirs@gmail.com,2018-06-12T12:30:00.00-07:00,-123.2898126,48.72724157,yes,"Estimated time and location, northbound toward Swansons",,,J,,,,,,,,,,, 26 | 1535761588007,2018-09-01T00:26:28.007Z,visual,sveirs@gmail.com,2018-06-12T13:00:00.00-07:00,-123.247387,48.69260618,yes,"Turn Point, time unclear",,,L,"L4s, L26s, L47s, L72s went Spieden",,,,,,,,,, 27 | 1535761721544,2018-09-01T00:28:41.544Z,visual,sveirs@gmail.com,2018-06-12T13:30:00.00-07:00,-123.3488218,48.78110898,yes,"Estimated time and location, northbound toward Active Pass",,,J,,,,,,,,,,, 28 | 1535761724727,2018-09-01T00:28:44.727Z,visual,sveirs@gmail.com,2018-06-12T14:30:00.00-07:00,-123.3091041,48.85881551,yes,J pod photographed at 14:30 in/near Active Pass northbound,,,J,,,,,,,,,,, 29 | 1535761589797,2018-09-01T00:26:29.797Z,visual,sveirs@gmail.com,2018-06-12T15:00:00.00-07:00,-123.0307671,48.77921167,yes,"East Point, Saturna, time unclear",,,L,"L4s, L26s, L47s, L72s went Spieden",,,,,,,,,, 30 | 1535761726744,2018-09-01T00:28:46.744Z,visual,sveirs@gmail.com,2018-06-12T15:30:00.00-07:00,-123.2432861,48.93192875,yes,"Estimated time and location, northbound toward Fraser",,,J,,,,,,,,,,, 31 | 1535762122559,2018-09-01T00:35:22.559Z,visual,sveirs@gmail.com,2018-06-13T14:30:00.00-07:00,-123.2156752,48.59142738,yes,"remaining Ls came down, not the Js (Monika)",,,L,"L4s, L26s, L47s, L72s",,1,,,,,,,, 32 | 1535762115962,2018-09-01T00:35:15.962Z,visual,sveirs@gmail.com,2018-06-13T15:30:00.00-07:00,-123.2512476,48.6853625,yes,"remaining Ls came down, not the Js (Monika)",,,L,"L4s, L26s, L47s, L72s",,1,,,,,,,, 33 | 1535762318493,2018-09-01T00:38:38.493Z,visual,sveirs@gmail.com,2018-06-13T16:10:00.00-07:00,-123.1662365,48.51187868,yes,Off open bay with WW boats (Alisa),,,L,"L4s, L26s, L47s, L72s",,1,,,,,,,, 34 | 1535762310871,2018-09-01T00:38:30.871Z,visual,sveirs@gmail.com,2018-06-13T17:30:00.00-07:00,-123.2054291,48.57612224,yes,"past LK lighthouse still spread widely (primarily in 1-3s) from inshore to offshore, steady pace southbound in rough seas (Alisa)",,,L,"L4s, L26s, L47s, L72s",,1,,,,,,,, 35 | 1535762484522,2018-09-01T00:41:24.522Z,visual,sveirs@gmail.com,2018-06-13T18:45:00.00-07:00,-123.1353048,48.48785886,yes,Passing Hannah Heights 6-6:45pm (Alisa),,,L,"L4s, L26s, L47s, L72s",,1,,,,,,,, 36 | 1535762497930,2018-09-01T00:41:37.930Z,visual,sveirs@gmail.com,2018-06-13T21:00:00.00-07:00,-123.0937525,48.45297087,yes,Hdg SW at sunset (Monika),,,L,"L4s, L26s, L47s, L72s",,1,,,,,,,, 37 | 1535762763886,2018-09-01T00:46:03.886Z,visual,sveirs@gmail.com,2018-06-14T09:15:00.00-07:00,-123.1859297,48.56428786,yes,6 orcas off Smugglers (Holly),,,J,,,,,,,,,,, 38 | 1535762766555,2018-09-01T00:46:06.555Z,visual,sveirs@gmail.com,2018-06-14T10:15:00.00-07:00,-123.1623411,48.5129874,yes,Calls and clicks and ship on LK hydrophone (942-1035),,,J,,,,,,,,,,, 39 | 1536097429773,2018-09-04T21:43:49.773Z,visual,cpsarason@gmail.com,2018-07-31T15:15:00.00-0700,-123.0030816,48.43482309,yes,There are whales offshore of South Beach heading north towards San Juan Island - reportedly J-Pod and the L12 sub-group. -Monika Wieland Shields,,,,,,,,,,,,,, 40 | 1536097430680,2018-09-04T21:43:50.680Z,visual,cpsarason@gmail.com,2018-07-31T15:15:00.00-0700,-123.0055133,48.43574506,yes,There are whales offshore of South Beach heading north towards San Juan Island - reportedly J-Pod and the L12 sub-group. -Monika Wieland Shields,,,,,,,,,,,,,, 41 | 1536097431784,2018-09-04T21:43:51.784Z,visual,cpsarason@gmail.com,2018-07-31T15:15:00.00-0700,-123.008293,48.43682091,yes,There are whales offshore of South Beach heading north towards San Juan Island - reportedly J-Pod and the L12 sub-group. -Monika Wieland Shields,,,,,,,,,,,,,, 42 | 1536097432933,2018-09-04T21:43:52.933Z,visual,cpsarason@gmail.com,2018-07-31T15:15:00.00-0700,-123.011073,48.43828141,yes,There are whales offshore of South Beach heading north towards San Juan Island - reportedly J-Pod and the L12 sub-group. -Monika Wieland Shields,,,,,,,,,,,,,, 43 | 1536096928431,2018-09-04T21:35:28.431Z,visual,cpsarason@gmail.com,2018-07-31T16:30:00.00-0700,-123.154488,48.51470762,yes,They (residents) are now just north of Eagle Point. Going north. I can see a few at Pile Point as well. -Chris Wilson,,,,,,,,,,,,,, 44 | 1535752948782,2018-08-31T22:02:28.782Z,visual,wygtya@gmail.com,2018-07-31T17:00:00.00-07:00,-123.1746716,48.51269782,yes,"Yesterday (July 31), J-Pod was joined by a large portion of L-Pod in the Salish Sea. We saw them as they headed north past Lime Kiln in the late afternoon. J47 Notch, pictured here, has, when we have seen him, been going back and forth between his grieving mother J35 Tahlequah and hanging out with some other young males in J-Pod. Yesterday he was in with J38 Cookie and L105 Fluke, among others. J50 Scarlet was present also. (The August 1 update is J35 Tahlequah is still carrying her deceased daughter, for nine days now. It's difficult to imagine what she has been going through or the effort required to carry her baby hundreds of miles. We hope she finds the right time to let go, and that the body of her newborn returns peacefully to the sea. We are all struggling alongside her as we watch from afar, with a renewed fire to do whatever we can on behalf of the Southern Residents.) -Monika Wieland Shields, OBI",,,J+L,,"J47, J35, J38, L105, J50",2018-07-31,,,,,,,, 45 | 1536096928431,2018-09-04T21:35:28.431Z,visual,cpsarason@gmail.com,2018-07-31T17:28:00.00-0700,-123.154488,48.51470762,yes,"Members of J-Pod (plus some others - at least the L72s were present!) passed Lime Kiln going north. J35 and J50 were both there, as was we believe all of J-Pod. -Monika Wieland Shields",,,,,,,,,,,,,, 46 | 1536096929546,2018-09-04T21:35:29.546Z,visual,cpsarason@gmail.com,2018-07-31T17:30:00.00-0700,-123.1546561,48.51526439,yes,"Members of J-Pod (plus some others - at least the L72s were present!) passed Lime Kiln going north. J35 and J50 were both there, as was we believe all of J-Pod. -Monika Wieland Shields",,,,,,,,,,,,,, 47 | 1536096932244,2018-09-04T21:35:32.244Z,visual,cpsarason@gmail.com,2018-07-31T17:32:00.00-0700,-123.1552025,48.51598818,yes,"Members of J-Pod (plus some others - at least the L72s were present!) passed Lime Kiln going north. J35 and J50 were both there, as was we believe all of J-Pod. -Monika Wieland Shields",,,,,,,,,,,,,, 48 | 1536096704705,2018-09-04T21:31:44.705Z,visual,cpsarason@gmail.com,2018-07-31T17:50:00.00-0700,-123.0388268,48.4565411,yes,"And tight knit group of 6 very close to shore just passed Eagle Cove, northbound. -Lodie Gilbert Budwill",,,,,,,,,,,,,, 49 | 1536095718940,2018-09-04T21:15:18.940Z,visual,cpsarason@gmail.com,2018-07-31T21:30:00.00-07:00,-123.1624423,48.54143505,yes,"Per my friend Ariel Yseth at Land Bank, L Pod is at San Juan County Park, id'd as Mega, Spirit, Solstice and 7-8 others. Moving Slowly- fishing. I've been listening to them on Lime Kiln Hydrophone for about 10-15 minutes. General direction southbound....They came in very close to shore at Land Bank,. kelped, and departed SB at 22:00 per Ariel. -Donna Van Renselaar",,,,,,,,,,,,,, 50 | 1552079658922,2019-03-08T21:14:18.922Z,visual,sveirs@gmail.com,2019-03-08T10:30:00.00-08:00,-122.4558895,48.07966378,yes,At least 3 orcas southbound off Bell's Beach in Sarasota Passage,ON call,,B,T99s,,20190308A,,,,,,,, 51 | 1552080656266,2019-03-08T21:30:56.266Z,visual,sveirs@gmail.com,2019-03-08T12:30:00.00-08:00,-122.3616069,48.01619382,yes,3/4 - 1 mile south of Sandy Point southbound,ON call,,B,T99s,,20190308A,,,,,,,, 52 | 1552081600636,2019-03-08T21:46:40.636Z,visual,sveirs@gmail.com,2019-03-08T12:45:00.00-08:00,-122.3545429,48.01611938,yes,"T99's, 4 whales, foraging, having a meal, no direction",ON call,,B,T99s,,20190308A,,,,,,,, 53 | 1552093533740,2019-03-09T01:05:33.740Z,visual,sveirs@gmail.com,2019-03-08T16:30:00.00-08:00,-122.4218935,47.85108742,yes,T99's in Puget Sound (2-3 mi S of Scatchet Head),ON call,,B,T99s,,20190308A,,,,,,,, 54 | 1552717650349,2019-03-16T06:27:30.349Z,visual,sveirs@gmail.com,2019-03-09T11:38:00.00-08:00,-122.9493157,48.54038847,yes,"T123s and T124As off of Foster Point, near the east entrance of Harney Channel. The whales were all grouped up and zig-zagging their way toward Obstruction Pass. Surfacing beside T124A3 was a new calf, likely born at the beginning of 2019. T123’s calf that was born in late 2018 was also present.",CWR report,,B,"T123s, T124As",,20190309A,,,,,,,, 55 | 1552717687920,2019-03-16T06:28:07.920Z,visual,sveirs@gmail.com,2019-03-09T11:38:00.00-08:00,-122.788374,48.52900832,yes,"At 1541, the whales swam through Obstruction Pass and entered Rosario Strait. Once in Rosario, the T123s and T124As zig-zagged their way northwest. The encounter was ended at 1630 as the whales made a turn to the north, just south of Peapod Rocks. No kills were observed during the encounter.",CWR report,,B,"T123s, T124As",,20190309A,,,,,,,, 56 | 1552717719191,2019-03-16T06:28:39.191Z,visual,sveirs@gmail.com,2019-03-09T11:38:00.00-08:00,-122.8009394,48.59913317,yes,transient killer whales eastbound off the south end of Shaw Island,CWR report,,B,,,,,,,,,,, 57 | 1552717698601,2019-03-16T06:28:18.601Z,visual,sveirs@gmail.com,2019-03-09T12:00:00.00-08:00,-122.8877636,48.58441563,yes,group of transients was found entering Thatcher Pass from Rosario Strait,CWR report,,B,,,,,,,,,,, 58 | 1552494539792,2019-03-13T16:28:59.792Z,visual,sveirs@gmail.com,2019-03-12T11:35:00.00-08:00,-122.3124904,47.95181227,yes,WSF captain report 3-4 orca northbound off Mukilteo ferry terminal,ON call,,B,T137s,,20190312A,,,,,,,, 59 | 1552504872420,2019-03-13T19:21:12.420Z,visual,sveirs@gmail.com,2019-03-12T11:35:00.00-08:00,-122.3174334,47.93971128,yes,"Went in towards Everett and made a kill, then turned around",ON call,,B,T137s,,20190312A,,,,,,,, 60 | 1552504868636,2019-03-13T19:21:08.636Z,visual,sveirs@gmail.com,2019-03-12T13:10:00.00-08:00,-122.275097,47.96511918,yes,Southbound at south end of Mukilteo Beach Park (likely staying in Puget Sound?),ON call,,B,T137s,,20190312A,,,,,,,, 61 | 1552546578570,2019-03-14T06:56:18.570Z,visual,sveirs@gmail.com,2019-03-13T18:20:00.00-08:00,-122.6416295,48.074186,yes,southbound unknown # of orcas off Lagoon Point,ON call,,,,,,,see text msg,,,,,, 62 | 1552609886426,2019-03-15T00:31:26.426Z,visual,sveirs@gmail.com,2019-03-14T10:30:00.00-08:00,-122.3992488,47.42118638,yes,~9 orcas (including 3 males) have been stalled enjoying large meal mid-channel between Three Tree Point (Burien) and just south of Tramp Harbor Vashon for past two hours. Still there (12:30 update texted at 12:34).,ON call,,B,"T46s, T137s?",,20190314A,,,,,,,, 63 | 1552931614546,2019-03-18T17:53:34.546Z,visual,sveirs@gmail.com,2019-03-14T10:30:00.00-08:00,-123.264508,48.65603286,yes,"Tom Cogan called Dave late morning to report that they were hearing whales on the hydrophone. After spotting them, the Cogans went out on their boat “Morning Star” with Melisa Pinnow aboard and called again to say that they had identified the whales as the T10s and T2Cs and that they were heading north near Gooch Island",CWR report,,B,"T10s, T2Cs",,20190314B,,,,,https://www.google.com/url?q=https://www.whaleresearch.com/2019-16&sa=D&ust=1552935737802000&usg=AFQjCNFBGOeTL8xWpXcMSiA060tEaDUYhA,,, 64 | 1552932503488,2019-03-18T18:08:23.488Z,visual,sveirs@gmail.com,2019-03-14T12:20:00.00-08:00,-123.2940705,48.73231402,yes,"“Orcinus” arrived on scene around 1220 where the T10s and the T2Cs, minus T2C2 and T2C3, were traveling slowly north tight to the east shoreline of Moresby Island. Several whales from this group stopped and briefly logged at the surface.",CWR report,,B,"T10s, T2Cs",,20190314B,,,,,https://www.google.com/url?q=https://www.whaleresearch.com/2019-16&sa=D&ust=1552935737802000&usg=AFQjCNFBGOeTL8xWpXcMSiA060tEaDUYhA,,, 65 | 1552609882126,2019-03-15T00:31:22.126Z,visual,sveirs@gmail.com,2019-03-14T12:34:00.00-08:00,-122.3999566,47.42932641,yes,~9 orcas (including 3 males) have been stalled enjoying large meal mid-channel between Three Tree Point (Burien) and just south of Tramp Harbor Vashon for past two hours. Still there (12:30 update texted at 12:34).,ON call,,B,"T46s, T137s?",,20190314A,,,,,,,, 66 | 1552932987171,2019-03-18T18:16:27.171Z,visual,sveirs@gmail.com,2019-03-14T12:45:00.00-08:00,-123.0368886,48.77499488,yes,"“Morning Star” had left the scene a while ago and had gone on a whale search up Boundary Pass toward East Point. A bit before 1300, they found the T49As near East Point heading quickly southwest down Boundary Pass.",CWR report,,B,T49As,,,,,,,,,, 67 | 1552932644654,2019-03-18T18:10:44.654Z,visual,sveirs@gmail.com,2019-03-14T13:10:00.00-08:00,-123.3426875,48.75955629,yes,"After a long dive, the whales moved more into the middle of lower Swanson Channel and began to wake up a bit. T10 did two big cartwheels and T2C did one. A whale appeared from the north and this turned out to be T2C3. T2C3 logged briefly at the surface about a quarter of a mile north of the other whales when all the whales went on another long dive. When the whales came up again, T2C3 had re-joined the group and everybody continued north.",CWR report,,B,"T10s, T2Cs",,20190314B,,,,,,,, 68 | 1552933126887,2019-03-18T18:18:46.887Z,visual,sveirs@gmail.com,2019-03-14T13:30:00.00-08:00,-123.1646414,48.70807618,yes,"“Orcinus” left the T2Cs and T10s at about 1310 in mid-Swanson Channel to head over to where the T49As were in Boundary Pass, arriving on scene mid-way between Blunden Island and Johns Pass twenty minutes later.",CWR report,,B,T49As,,,,,,,,,, 69 | 1552676601214,2019-03-15T19:03:21.214Z,visual,sveirs@gmail.com,2019-03-14T14:00:00.00-08:00,-122.4662518,47.52232232,yes,T46s & T137s last reported at 14:00 northbound off north end of Vashon on Vashon Side. Unclear if continued north or around Blake or Colvos? No sightings since (text at 14:47).,ON text,,B,"T46s, T137s",,20190314A,,,,,,,, 70 | 1552609682012,2019-03-15T00:28:02.012Z,visual,sveirs@gmail.com,2019-03-14T16:10:00.00-08:00,-122.4742859,47.63417646,yes,"T46s and T137s currently grouped up & northbound north of Eagle Harbor, Bainbridge on that side of channel.",ON text,,B,"T46s, T137s?",,20190314A,,,,,,,, 71 | 1552587961556,2019-03-14T18:26:01.556Z,visual,sveirs@gmail.com,2019-03-14T18:20:00.00-08:00,-122.4156858,47.51960589,yes,3-4 orcas w/one big male southbound off Fauntleroy ferry dock (2 groups inbound last night: T137s and possibly T46s - maybe split up?),ON text,,B,"T46s, T137s?",,20190314A,,,,,,,, 72 | 1552931221850,2019-03-18T17:47:01.850Z,visual,sveirs@gmail.com,2019-03-18T08:44:00.00-08:00,-122.5375081,47.32888196,yes,orca: 08:44 - 5+ orcas (poss 1 male) very spread out in Dalco Passage (between S Vashon/Pt Defiance) moving vigorously southbound towards Tacoma Narrows. No IDs. (8:52 text),ON text,,,,,,,,,,,,, 73 | 1553331428916,2019-03-23T08:57:08.916Z,acoustic,sveirs@gmail.com,2019-03-19T00:02:00.00-08:00,-123.1735457,48.55153945,yes,~1:57 a.m. local time I heard ~4 SRKW calls repeated in a short ~20 second period,Orcasound Lab,,,,,,,"Calls occurred approximately between .ts segments 137 and 170 of https://s3-us-west-2.amazonaws.com/streaming-orcasound-net/rpi_orcasound_lab/hls/1553329934/live.m3u8 and that datetime stamp indicates recording began at GMT: Saturday, March 23, 2019 8:32:14 AM 74 | Your time zone: Saturday, March 23, 2019 1:32:14 AM GMT-07:00 DST so 1:57-1:32 =~ 25 min into the recording. (Replayed 27:00-31:00 and heard no calls, just slowly rising ship noise.) Faint single call at 20:46 into recording, another single at 21:00, and then the bout: two different calls at 21:29, 21:32; the same two repeated in the same sequence at 21:36 and 21:39; and again at 21:43 and 21:46. First call type is a long S22; the second in the repeated pair is S42. So if we say the clear S22 and S42 calls began at 21:29 into the recording that began at 1:32:14, then the local time at the start of the sequence was 1:53:43 and it lasted for 27 seconds. There were consistently 3 seconds between the S22 and S42 calls, and then a pause of 4 seconds before the next S22/42 pair.",,,,,, 75 | 1553033080193,2019-03-19T22:04:40.193Z,visual,sveirs@gmail.com,2019-03-19T11:35:00.00-08:00,-122.6834412,47.34802653,yes,"11:35 - Ts (presume some/all yesterday's) southern Puget Sound, Henderson Bay (upper Carr Inlet) making directional changes. Some were SB ealier, at least 2 NB towards Purdy Spit, maybe split? (11:42 text)",ON text,,B,,,,,,,,,,, 76 | 1553629426133,2019-03-26T19:43:46.133Z,hearsay,vveirs@coloradocollege.edu,2019-03-25T12:30:00.00-08:00,-123.1262972,48.72886465,Yes,12:20 Dave E from CWR reports J pod southbound in Boundary Pass,Val,,,,,,,,,,,,, 77 | 1553974235512,2019-03-30T19:30:35.512Z,visual,sveirs@gmail.com,2019-03-25T12:30:00.00-08:00,-123.1882018,48.55368961,No,First sighting of northbound orcas about 1 km offshore w/recreational whale watcher,,,,,,,,,,,,,, 78 | 1554590748895,2019-04-06T22:45:48.895Z,visual,sveirs@gmail.com,2019-04-06T15:17:00.00-08:00,-122.706856,48.13737259,Yes,orca: 3:17 - WS Ferries reports 6-8 orcas Admiralty Inlet (Port Townsend/Coupeville run) southbound in the traffic lanes.,ON text,,,,,,,,,,,,, 79 | 1554656821792,2019-04-07T17:07:01.792Z,visual,sveirs@gmail.com,2019-04-07T10:00:00.00-08:00,-122.4267761,47.79791529,Yes,"Orca: 10:00- residents in Puget Sound. Presume Js but not confirmed. Spread across channel off Point Wells and kingston, and just north of and south of. Active foraging. Slow trend northbound.",ON text,,,J?,,,,,,,,,, 80 | 1556219691516,2019-04-25T19:14:51.516Z,visual,sveirs@gmail.com,2019-04-21T13:00:00.00-08:00,-122.9884765,48.80016915,Yes,J pod heading NE with J16 trailing 1/2 mi to SW,CWR report,,,J,,"L87, J16s, J46, J47, and J51 ",,,,,,,https://www.whaleresearch.com/2019-27,NE 81 | 1556219680985,2019-04-25T19:14:40.985Z,visual,sveirs@gmail.com,2019-04-21T13:30:00.00-08:00,-122.9933536,48.77124848,Yes,"Fanning out northwestward near Alden Point, others socializing",CWR report,,,J,,"L87, J16s, J46, J47, and J51 ",,,,,,,,NW 82 | 1556219684575,2019-04-25T19:14:44.575Z,visual,sveirs@gmail.com,2019-04-21T14:05:00.00-08:00,-122.972157,48.79324948,Yes,Many moving west towards Tumbo or milling,CWR report,,,J,,"L87, J16s, J46, J47, and J51 ",,,,,,,,W 83 | 1556855641214,2019-05-03T03:54:01.214Z,visual,sveirs@gmail.com,2019-04-28T09:20:00.00-08:00,-122.4530951,47.70070324,Yes,"Bigg's killer whales southbound, hunting sea lion, may be stalled out.",ON text,,Killer whale,B,,,,,"orca: 09:20 - Transients southbound just north off Shilshole (N Seattle) in traffic separation zone. Then went hunting a sea lion, south of foxtrot buoy so may be stalled out.",,,,, 84 | 1556855684830,2019-05-03T03:54:44.830Z,visual,sveirs@gmail.com,2019-04-28T09:40:00.00-08:00,-122.623928,47.20580682,Yes,"Humpback, no direction provided",ON text,,Humpback whale,,,,,,humpback: 09:40 - whale reported as humpback off McNeil Island no direction provided.,,,,, 85 | 1556855264469,2019-05-03T03:47:44.469Z,visual,sveirs@gmail.com,2019-04-28T17:35:00.00-08:00,-122.3389087,47.89264879,Yes,Pod of orcas (probably morning group) northbound slow,ON text,,Killer whale,,,,,,orca: 5:35pm - Pod of orcas (probably morning group) northbound in southern end Possession Sound = 1+ mile north of Picnic Point in no hurry at time of report.,,,,, 86 | 1556855269857,2019-05-03T03:47:49.857Z,visual,sveirs@gmail.com,2019-04-28T19:00:00.00-08:00,-122.3533912,48.02459255,Yes,"Orcas (4, incl male) heading NW",ON text,,Killer whale,B,,,,,"orca: 7:00 pm - Orcas (4, incl male) just passed NW bound between NW Hat Island and Whidbey aiming for Saratoga Passage. IDs/photos appreciated.",,,,, 87 | 1556855085951,2019-05-03T03:44:45.951Z,visual,sveirs@gmail.com,2019-05-01T09:45:00.00-08:00,-122.6379976,48.16244426,Yes,"Gray whale, possibly feeding",ON text,,Gray,,,,,,"Gray: 09:45 - Gray whale Admiralty Bay south of Keystone ferry in front of development. Described feeding behavior, been there at least one hour. Any good ID photos appreciated.",,,,, 88 | 1559862513626,2019-06-06T23:08:33.626Z,visual,sveirs@gmail.com,2019-06-06T12:00:00.00-08:00,-122.7327914,48.46336064,Yes,"6-7 orcas (male, few females, juvie, calf) hdg NE",ON text,,Killer whale,,,,,,"Orcas (6-7 inc. male, few females, juvie, calf) reported in Rosario Strait heading towards Allan & Burrows Islands. Were traveling NE bound, now possibly heading between the islands.",,,,, 89 | 1560444031911,2019-06-13T16:40:31.911Z,visual,sveirs@gmail.com,2019-06-12T09:45:00.00-08:00,-122.3256647,47.95579155,"effort, no sightings","scanned north on ferry crossing. saw only 3 gull, no marmams",Orcamap,,None,,,,,,,,,,, 90 | 1560449733589,2019-06-13T18:15:33.589Z,visual,alisalemire@gmail.com,2019-06-13T09:03:00.00-08:00,-122.3942007,47.83439538,Yes,Humpback,ON text,,,,,,,,,,,,, 91 | 1560449822616,2019-06-13T18:17:02.616Z,visual,sveirs@gmail.com,2019-06-13T09:20:00.00-08:00,-122.4419279,47.80393704,Yes,"Humpback Shell, MMX0049",ON text,,,,,,,,,,,,, 92 | 1560472431080,2019-06-14T00:33:51.080Z,visual,sveirs@gmail.com,2019-06-13T16:30:00.00-08:00,-122.3201454,47.95933152,"effort, no sightings",scanned south on ferry crossing. saw no marmams,,,,,,,,,,,,,, 93 | 1560551755453,2019-06-14T22:35:55.453Z,visual,alisalemire@gmail.com,2019-06-14T09:25:00.00-08:00,-122.6117881,48.02284588,Yes,"4 orcas, inc. male SB (prob T137s)",Alisa using app!,,Killer whale,B,,,,,,,,,, 94 | 1560551639003,2019-06-14T22:33:59.003Z,visual,alisalemire@gmail.com,2019-06-14T10:30:00.00-08:00,-122.5623757,47.96639616,Yes,T137s predate on harbor seal,Alisa!,,Killer whale,B,,,,,,,,,, 95 | 1560563406291,2019-06-15T01:50:06.291Z,visual,sveirs@gmail.com,2019-06-14T15:45:00.00-08:00,-122.3045747,47.98293696,Yes,"orcas, inc male (on kill? no dir; T137s?))",ON text,,Killer whale,B,,,,,orca: 15:45 - Orcas ( inc male) in Possession Sound 3/4 mile south of Hat Island halfway between Whidbey and Everett. Sounds like possibly on a meal. No direction at the time. Presumably T137s.,,,,, 96 | 1560885158059,2019-06-18T19:12:38.059Z,visual,sveirs@gmail.com,2019-06-17T18:50:00.00-08:00,-122.4870664,47.84199816,Yes,T137s northbound,ON text,,Killer whale,B,,,,,"After a directional change, T137s have resumed northbound travels, have passed Apple Tree Point, Kingston heading towards Eglon, close to Kitsap shore. Last alert for the day, see our FB page for any updates.",,,,, 97 | 1561527970922,2019-06-26T05:46:10.922Z,visual,sveirs@gmail.com,2019-06-24T12:00:00.00-08:00,-123.4011661,48.1567493,Yes,Time & ecotype TBD; off Ediz Hook near PA.,Facebook,,Killer whale,,,,,, - Orcas off Ediz Hook spit in Port Angeles. Reported by Puget Sound Pilots.,2 breach pix...,https://www.facebook.com/PugetSoundPilots/posts/2343101715782101,,https://www.facebook.com/PugetSoundPilots/posts/2343101715782101, 98 | 1561506471589,2019-06-25T23:47:51.589Z,visual,sveirs@gmail.com,2019-06-25T14:35:00.00-08:00,-122.6879566,48.40775515,Yes,Orcas southbound off Deception,ON text,,Killer whale,,,,,,"15:30 - Orcas off west side Whidbey, believe currently near NAS Whidbey. They came from the north, reported off Deception Pass at 14:35.",,,,, 99 | 1561506485161,2019-06-25T23:48:05.161Z,visual,sveirs@gmail.com,2019-06-25T15:30:00.00-08:00,-122.6937678,48.36195716,Yes,"Orcas off west side Whidbey, believe currently near NAS Whidbey",ON text,,Killer whale,,,,,,"15:30 - Orcas off west side Whidbey, believe currently near NAS Whidbey. They came from the north, reported off Deception Pass at 14:35.",,,,, 100 | 1553974195828,2019-03-30T19:29:55.828Z,visual,sveirs@gmail.com,Enter ,-123.2019323,48.55359468,No,First group continuing northbound near Kellett Bluff,,,,,,,,,,,,,, 101 | 1553974237722,2019-03-30T19:30:37.722Z,visual,sveirs@gmail.com,Enter ,-123.1923613,48.56938075,No,2nd group northbound ~250m offshore,,,,,,,,,,,,,, 102 | 1553974222112,2019-03-30T19:30:22.112Z,visual,sveirs@gmail.com,Enter ,-123.1858156,48.56684041,No,"2nd group proceeding northbound, heard two S4 calls over significant ship noise",,,,,,,,,,,,,, 103 | 1553974213042,2019-03-30T19:30:13.042Z,visual,sveirs@gmail.com,Enter ,-123.1791644,48.55527759,No,2nd group continuing north near Kellett Bluff,,,,,,,,,,,,,, 104 | 1553974202669,2019-03-30T19:30:02.669Z,visual,sveirs@gmail.com,Enter ,-123.2004947,48.57649145,No,3rd group surfing soliton,,,,,,,,,,,,,, 105 | 1553974229719,2019-03-30T19:30:29.719Z,visual,sveirs@gmail.com,Enter ,-123.1854981,48.53716736,No,3rd group passes Orcasound Lab surfing (no calls?),,,,,,,,,,,,,, 106 | 1553974210578,2019-03-30T19:30:10.578Z,visual,sveirs@gmail.com,Enter ,-123.1811288,48.54444117,No,3rd group continues surfing northward,,,,,,,,,,,,,, 107 | 1562655050220,2019-07-09T06:50:50.220Z,visual,sveirs@gmail.com,2019-07-05T08:05:00.00-08:00,-123.1802118,48.55223589,Yes,JK pods northbound (CWR report #43),CWR,,Killer whale,JK(L?),"J19s, K12s, K13s","K38, J51",,,"The leaders were first encountered at 0805 off CWR. The whales were spread out and heading north with members of the J19s, K12s, and K13s in the lead. Some whales made it past Kellett Bluff whiles others foraged deep into Mitchell Bay. K38 and J51 were playing and splashing around together.",,,,https://www.whaleresearch.com/2019-43,N 108 | 1562655267139,2019-07-09T06:54:27.139Z,visual,sveirs@gmail.com,2019-07-05T09:15:00.00-08:00,-123.184867,48.57913698,Yes,JK pods southbound (CWR report #43),CWR,,Killer whale,JK(L?),,,,,"By 0915, most of the whales had turned around and began heading south down the west side of San Juan Island.",,,,https://www.whaleresearch.com/2019-43,S 109 | 1562349154545,2019-07-05T17:52:34.545Z,visual,sveirs@gmail.com,2019-07-05T09:34:00.00-08:00,-123.1899069,48.55678519,Yes,"Text from Alisa: ""SRKWs in Haro. Currently on OS.""",Alisa txt2 SV,,Killer whale,JK(L?),,,,,,,,,,S 110 | 1562655477153,2019-07-09T06:57:57.153Z,visual,sveirs@gmail.com,2019-07-05T10:15:00.00-08:00,-123.103627,48.47628721,Yes,JK pods Hannah Heights to Eagle Point (CWR report #43),CWR,,Killer whale,JK(L?),,,,,"About an hour later, J and K pods were spread out from Hannah Heights to Eagle Point. A few individual whales were foraging offshore while a few small groups were spread out closer to shore. The new J pod calf was found inshore in a small group just north of Eagle Point. The calf was traveling with J31 but several other young females were with them too as the whales turned back north again. J40 and J46 seemed particularly interested in the new calf. L87 also traveled briefly behind this group. Other small groups were in the area including one that had K16, K35, and J45 socializing together. K38 and J51 were still playing with each other.",,,,https://www.whaleresearch.com/2019-43,S 111 | 1562349156452,2019-07-05T17:52:36.452Z,visual,sveirs@gmail.com,2019-07-05T11:03:00.00-08:00,-123.1621979,48.51152637,Yes,"Facebook post from Donna Van Renselaar: ""They are all over in front of LK""",Facebook,,Killer whale,JK(L?),,,,,,,,,,SE 112 | 1562349163421,2019-07-05T17:52:43.421Z,visual,sveirs@gmail.com,2019-07-05T11:47:00.00-08:00,-123.038431,48.45183303,Yes,From FB post by Eagle Point resident (Holly Cannon),Facebook,,Killer whale,JK(L?),,,,,,,,,,SE 113 | 1562655624289,2019-07-09T07:00:24.289Z,visual,sveirs@gmail.com,2019-07-05T14:25:00.00-08:00,-123.1588273,48.51246998,Yes,JK pods near Lime Kiln (CWR report #43),CWR,,Killer whale,JK(L?),,,,,All the whales were heading slowly up island although there was a lot of milling along the way. J31 was seen pushing J56 around and both Dave and Ken (who arrived later after finishing his encounter with transients) got photos of J56’s belly to show that she is a female. The whales made it to Lime Kiln by about 1425 but then all the whales turned around and headed back south down the west side of San Juan Island.,,,,https://www.whaleresearch.com/2019-43,N 114 | 1562653285764,2019-07-09T06:21:25.764Z,visual,sveirs@gmail.com,2019-07-06T06:31:00.00-08:00,-123.311187,48.86304066,Yes,Post by Rachelle Hayden to Whale Sightings in SJ FB group; 30+ animals hdg NE,WSiSJ FBG,,Killer whale,,,,,,,,,,https://www.facebook.com/groups/217640418999356/permalink/476226536474075/,NE 115 | 1565232005279,2019-08-08T02:40:05.279Z,visual,sveirs@gmail.com,2019-08-07T13:15:00.00-08:00,-122.8237488,48.52995223,Yes,OBI comment/post: Ts - likely the T18s - heading NW from the west side of Thatcher Pass,WSiSJ FBG,,Killer whale,T,T18,,20190921A,,,,,,https://www.facebook.com/groups/217640418999356/permalink/495142331249162/,NW 116 | 1565232006955,2019-08-08T02:40:06.955Z,visual,sveirs@gmail.com,2019-08-07T15:50:00.00-08:00,-122.9117477,48.58776287,Yes,OBI comment: westbound Harney Channel,WSiSJ FBG,,Killer whale,T,T18,,20190921A,,,,,,https://www.facebook.com/groups/217640418999356/permalink/495142331249162/,W 117 | 1568143435895,2019-09-10T19:23:55.895Z,visual,sveirs@gmail.com,2019-09-10T10:10:00.00-08:00,-122.5178549,47.91233953,Yes,Unidentified juvenile humpback,ON text,,Humpback,,,,,,,,,,, 118 | 1568143437108,2019-09-10T19:23:57.108Z,visual,sveirs@gmail.com,2019-09-10T11:05:00.00-08:00,-122.5759083,47.99035103,Yes,Two Spot,ON text,,Humpback,,,,,,,,,,, 119 | 1568143438246,2019-09-10T19:23:58.246Z,visual,sveirs@gmail.com,2019-09-10T11:13:00.00-08:00,-122.6646524,48.05366412,Yes,Humpback (no direction),ON text,,Humpback,,,,,,,,,,, 120 | 1568745303046,2019-09-17T18:35:03.046Z,visual,sveirs@gmail.com,2019-09-17T08:30:00.00-08:00,-122.4631741,47.80032407,Yes,Male SRKW,ON text,,Killer whale,SRKW,,,,,"orca: 08:30 - Several reports coming in...orcas (no IDs) spread out Edmonds/Kingston area heading southbound. At least 6 on Edmonds side, others reported mid, earlier 07:30 report had male on Kingston side. All southbound. Please look for open saddle patches and forward any images. Thanks!",,,,, 121 | 1569097921577,2019-09-21T20:32:01.577Z,visual,sveirs@gmail.com,2019-09-21T09:25:00.00-08:00,-123.1580813,48.5135314,Yes,SRKWs visible (K+L pod calls heard),WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190921A,,"Residents on the west side of San Juan Island, audible on Lime Kiln hydrophone and visible on Lime Kiln webcam. Ks and Ls heard.",,,,https://www.facebook.com/groups/217640418999356/permalink/524201268343268/, 122 | 1569098162172,2019-09-21T20:36:02.172Z,visual,sveirs@gmail.com,2019-09-21T09:34:00.00-08:00,-123.1532994,48.50902964,Yes,SRKW S16 calls heard (K pod),WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190921A,,EJ Evans I definitely heard S16 calls.,,,,https://www.facebook.com/groups/217640418999356/permalink/524201268343268/, 123 | 1569098316825,2019-09-21T20:38:36.825Z,visual,sveirs@gmail.com,2019-09-21T10:47:00.00-08:00,-123.1596779,48.49965055,Yes,"SRKW Sbound stragglers at Land Bank, mid-Strait",WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190921A,,"Brittany Noelle They’re loosely spread out across Haro Strait, stragglers just passing Land Bank, mid strait.",,,,https://www.facebook.com/groups/217640418999356/permalink/524201268343268/, 124 | 1569099574692,2019-09-21T20:59:34.692Z,visual,sveirs@gmail.com,2019-09-21T11:55:00.00-08:00,-123.0543872,48.44948892,Yes,SRKW (leaders?) southbound at Eagle Point,WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190921A,,Chris Wilson: orcas at Eagle Point - heading south,,,,https://www.facebook.com/groups/217640418999356/, 125 | 1569099119234,2019-09-21T20:51:59.234Z,visual,sveirs@gmail.com,2019-09-21T12:01:00.00-08:00,-123.0407246,48.44415199,Yes,SRKWs with 85 boats (WDFW 15min away),WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190921A,,Brittany Noelle Kim Merriman I see no enforcement. I’m just south of eagle cove and count 85 boats. This is unreal,,,,https://www.facebook.com/groups/217640418999356/permalink/524201268343268/, 126 | 1569098845587,2019-09-21T20:47:25.587Z,visual,sveirs@gmail.com,2019-09-21T13:45:00.00-08:00,-122.9818838,48.4196972,Yes,SRKW via appox position of Western Explorer II from marinetraffic.com,SV,,Killer whale,"Ks, Ls",,,20190921A,,Facebook comment from Taylor Shedd: L pod (minus L12s who are probably out west) and K pod (minus K13s who are with Js in Puget Sound),Yes,https://photos.app.goo.gl/EeiVBFkp37BdPxWr8,,marinetraffic.com, 127 | 1569101720141,2019-09-21T21:35:20.141Z,visual,sveirs@gmail.com,2019-09-21T14:15:00.00-08:00,-123.0347077,48.42231743,Yes,SRKW via appox position of Island Explorer from marinetraffic.com,SV,,Killer whale,"Ks, Ls",,,20190921A,,,Yes,https://photos.app.goo.gl/xAJTBt3VKVp7hTsf9,,marinetraffic.com, 128 | 1569104550237,2019-09-21T22:22:30.237Z,visual,sveirs@gmail.com,2019-09-21T14:26:00.00-08:00,-123.1271545,48.49027708,Yes,SRKW (leaders?) Nbound at Hannah Heights,WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190921A,,Kersti Elisabeth Muul Right under Hannah heights,,,,https://www.facebook.com/groups/217640418999356/permalink/524351364994925/, 129 | 1569128299135,2019-09-22T04:58:19.135Z,visual,sveirs@gmail.com,2019-09-21T18:55:00.00-08:00,-123.1564612,48.50287723,Yes,SRKW (leaders?) Nbound heard at Lime Kiln,WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190921A,,Kelly Bouthillet Some calls on the Lime Kiln Hydrophone and seeing glimpses of them on the Desticam now (6:55 pm PST),,,,, 130 | 1569128431157,2019-09-22T05:00:31.157Z,visual,sveirs@gmail.com,2019-09-21T19:18:00.00-08:00,-123.1844106,48.55363484,Yes,SRKW (leaders?) Nbound heard at Orcasound Lab,WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190921A,,Meg Sellers On Orcalab now 7:18,,,,https://www.facebook.com/groups/217640418999356/permalink/524481304981931/, 131 | 1569128507543,2019-09-22T05:01:47.543Z,visual,sveirs@gmail.com,2019-09-21T19:29:00.00-08:00,-123.1951211,48.57322957,Yes,SRKW (leaders?) Nbound off Snug Harbor,WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190921A,,Brittany Noelle Residents just saw by us off Snug Harbor headed northbound.,,,,https://www.facebook.com/groups/217640418999356/permalink/524481304981931/, 132 | 1569286634913,2019-09-24T00:57:14.913Z,visual,sveirs@gmail.com,2019-09-23T17:37:00.00-08:00,-122.4771084,47.69772713,Yes,SRKW Nbound off Fay Bainbridge S.P.,WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190923A,,Ron Sorrell 5:37 obs from fay. passing in front of fay Bainbridge park. 3 or 4 individuals. One male? Slowly going north. Western quarter of the channel,,,,https://www.facebook.com/OrcaNetwork/posts/10162560526415601, 133 | 1569286923515,2019-09-24T01:02:03.515Z,visual,sveirs@gmail.com,2019-09-23T09:20:00.00-08:00,-122.4300345,47.80389866,Yes,SRKW Sbound between Apple Tree Cove Pt and Kingston spread about mid-channel,WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190923A,,"Sherman Page 9:20 Half a dozen orcas southbound between Apple Cove Point and Kingston. Most near the shipping lanes, but a couple closer to Edmonds. One male breached a few times mid channel.",,,,https://www.facebook.com/OrcaNetwork/posts/10162560526415601, 134 | 1569287080731,2019-09-24T01:04:40.731Z,visual,sveirs@gmail.com,2019-09-23T10:30:00.00-08:00,-122.4436073,47.7168089,Yes,SRKW Sbound spread between mid-Port Madison and Carkeek Park,WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190923A,,"Orca Network 10:30 - Orcas (members of J pod at least) are southbound mid Sound between mid Port Madison, Kitsap and Carkeek Park, Seattle.",,,,https://www.facebook.com/OrcaNetwork/posts/10162560526415601, 135 | 1569287229398,2019-09-24T01:07:09.398Z,visual,sveirs@gmail.com,2019-09-23T11:24:00.00-08:00,-122.4567617,47.6873067,Yes,SRKW Sbound off Shilshole wide spread mid-Sound ,WSiSJ FBG,,Killer whale,"Ks, Ls",,,20190923A,,"Danielle Carter 11:24- Watching from Sunset Hill. They are across from Shilshole, mid channel, looks like 6-8 and at least two males trending south. Really spread out.",,,,, 136 | 1569287375729,2019-09-24T01:09:35.729Z,visual,sveirs@gmail.com,2019-09-23T12:22:00.00-08:00,-122.4689142,47.64463697,Yes,SRKW Sbound wide spread mid-Sound to 2/3 across from Magnolia,WSiSJ FBG,,Killer whale,"Ks, Ls",,"J26, J47 and maybe K20",20190923A,,"12:22 -- Michelle Savoie Viewing from Magnolia. They are mid channel to 2/3 across to bainbridge. Just south of manitou, headed south. (At 12:21 Bonnie Gretz Orca Network J26, J47 and maybe K20)",,,,, 137 | 1573771996049,2019-11-14T22:53:16.049Z,visual,sveirs@gmail.com,2019-11-14T12:28:00.00-08:00,-122.6483911,48.07681063,Yes,SRKW Nbound off Lagoon Point mid-channel,ON FB,,Killer whale,Js,,,20191114,,"Benjamin Potter Lagoon point, north bound, mid channel, large group, blows and breaching. 12:28 At least 5. They were spread out with a very large one following behind.",,,,https://www.facebook.com/OrcaNetwork/posts/10162815987315601, 138 | 1573772771405,2019-11-14T23:06:11.405Z,visual,sveirs@gmail.com,2019-11-14T08:55:00.00-08:00,-122.4571364,47.83808253,Yes,SRKW S?bound in traffic separation lane spread between buoys SE & SF.,ON FB,,Killer whale,Js,,,20191114,,"James Greenway 08:50 - Good morning, I am unsure of the exact number but there 7+ Killer Whales in the Separation Zone between the traffic lanes off of Possession Pt. (South Whidbey). They appear to be headed Southbound. It looks like the group is fairly spread out between buoy SE and SF. The Victoria Clipper V is with them now (0850). 08:57 - Definitely more like 15+ animals, just a very wide spread….Also a single Minke Whale just north of buoy SE, in the middle of the spread of killer whales.",,,,https://www.facebook.com/OrcaNetwork/posts/10162815987315601, 139 | 1573774013522,2019-11-14T23:26:53.522Z,acoustic,sveirs@gmail.com,2019-11-14T12:57:00.00-08:00,-122.6642267,48.10970407,Yes,J pod calls heard on both Port Townsend & Bush Point hydrophones. (12:53 1st PT tag),ON FB,,Killer whale,Js,,,20191114,,ON sightings suggest group was spread from near ,,,,, 140 | 1573774861368,2019-11-14T23:41:01.368Z,visual,sveirs@gmail.com,2019-11-14T13:22:00.00-08:00,-122.6742997,48.12123273,Yes,J pod from Fort Casey Nbound mid-channel still south of ferry lanes,ON FB,,Killer whale,Js,,,20191114,,Josh Haight 1:22 viewing from Fort Casey mid channel still south of ferry lanes,,,,,NW 141 | 1573774892030,2019-11-14T23:41:32.030Z,visual,sveirs@gmail.com,2019-11-14T13:44:00.00-08:00,-122.68833,48.13035776,Yes,J pod Nbound mid-channel approaching ferry lanes,ON FB,,Killer whale,Js,,,20191114,,Rachel Haight 144 steady travel northbound spread out long down times approaching ferry lanes; no boats in sight in either direction so definitely listen to the calls!,,,,,NW 142 | 1573775393000,2019-11-14T23:49:53.000Z,visual,sveirs@gmail.com,2019-11-14T13:55:00.00-08:00,-122.6980432,48.14524247,Yes,J pod Nbound mid-channel N of ferry lanes spread Fort Casey to Point Wilson,ON FB,,Killer whale,Js,,,20191114,,Rachel Haight 155 starting to group up Whidbey side. Couple of groups spread north to south and east to west. Northbound edit: some of Pt side too. Long downtimes still.,,,,,NW 143 | 1573775685769,2019-11-14T23:54:45.769Z,visual,sveirs@gmail.com,2019-11-14T14:18:00.00-08:00,-122.7123802,48.15442703,Yes,"J pod Nbound mid-channel, leaders near Fort Warden from Fort Casey, spread NSEW",ON FB,,Killer whale,Js,,,20191114,,"Rachel Haight 218 ferry slowed for trailing groups. Still spread out. Seem to be midchannel, leaders pushing NW and approaching Fort Worden area",,,,,NW 144 | 1573861755497,2019-11-15T23:49:15.497Z,visual,sveirs@gmail.com,2019-11-14T15:36:00.00-08:00,-122.7429573,48.17496946,Yes,J pod NWbound mid-channel from crossed bearings by 2 ON sightings from FB page,ON FB,,Killer whale,Js,,,20191114,,"Mary Bond Watching from Point Wilson Lighthouse, I can see 5-10 orca whales headed NNW along Whidbey Island from Ebey’s Landing north towards Fort Ebey; David Haeckel Just saw a breach near Protection Island, west end; David Haeckel They are on the Eastside of Protection Island, continuing north! David Haeckel Last of the Pod passing McCurdy Point on their way North. Picture from Hill Road on Whidbey. Thank you Orca Network Folks for all the updates allowing me to be able to see them before they head out! We think 🤔",,,,,NW 145 | 1574619472967,2019-11-24T18:17:52.967Z,visual,sveirs@gmail.com,2019-11-23T08:15:00.00-08:00,-122.701733,48.13476977,Yes,J pod inbound?,ON FB,,Killer whale,Js,,,,,"ON tweet: orca: 2nd hand report: 08:15 - 2 orcas seen southbound from the Port Townsend/Keystone ferry run. Will update if/when get anything, please let us know if you do. Thanks and happy whale watching.",,,,, 146 | 1574623482114,2019-11-24T19:24:42.114Z,acoustic,sveirs@gmail.com,2019-11-20T18:03:00.00-08:00,-123.1534812,48.51151765,Yes,orcas heard on LK hp,WSiSJ FBG,,Killer whale,,,,,,"Just tuned in to LK hydrophone and I’m hearing calls! Not a lot but they are there! Loud ship passing at the moment, hopefully they’re still around after it passes 😩",,,,https://www.facebook.com/groups/217640418999356/permalink/571553940274667/, 147 | 1579798628533,2020-01-23T16:57:08.533Z,visual,sveirs@gmail.com,2020-01-23T08:17:00.00-08:00,-122.4212754,47.46595946,Yes,orcas southbound at Dilworth.,313131,,SRKW,J+K,,,200123a,no?,Good morning! We have orcas headed southbound at Dilworth. May still catch some there -- otherwise point Robinson in an hour or so if they keep going south.,,,,, 148 | 1579799150501,2020-01-23T17:05:50.501Z,visual,sveirs@gmail.com,2020-01-23T08:35:00.00-08:00,-122.4022532,47.4366862,Yes,"12+ orcas Sbound, likely J+Ks",ON txt,,SRKW,J+K,,,200123a,yes,08:35 - 1st group at least some south of Three Tree heading south towards Point Robinson.,,,,, --------------------------------------------------------------------------------