-
Notifications
You must be signed in to change notification settings - Fork 374
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* click overlay to preview * updatea cluster plugin --------- Co-authored-by: zhouwenxuan <[email protected]>
- Loading branch information
1 parent
0b0e471
commit 076d147
Showing
7 changed files
with
144 additions
and
1,867 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,69 @@ | ||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; | ||
import React, { useEffect, useMemo } from 'react'; | ||
import { getFileNameFromRecord, getFileTypeFromRecord, getImageLocationFromRecord, getParentDirFromRecord, getRecordIdFromRecord } from '../../utils/cell'; | ||
import ClusterPhotos from './cluster-photos'; | ||
import MapView from './map-view'; | ||
import { PREDEFINED_FILE_TYPE_OPTION_KEY } from '../../constants'; | ||
import { useMetadataView } from '../../hooks/metadata-view'; | ||
import { Utils } from '../../../utils/utils'; | ||
import { gettext, siteRoot, thumbnailSizeForGrid } from '../../../utils/constants'; | ||
import { fileServerRoot, siteRoot, thumbnailSizeForGrid, thumbnailSizeForOriginal } from '../../../utils/constants'; | ||
import { isValidPosition } from '../../utils/validate'; | ||
import { gcj02_to_bd09, wgs84_to_gcj02 } from '../../../utils/coord-transform'; | ||
import { PRIVATE_FILE_TYPE } from '../../../constants'; | ||
|
||
import './index.css'; | ||
|
||
const Map = () => { | ||
const [showCluster, setShowCluster] = useState(false); | ||
const { metadata, viewID, updateCurrentPath } = useMetadataView(); | ||
|
||
const clusterRef = useRef([]); | ||
|
||
const repoID = window.sfMetadataContext.getSetting('repoID'); | ||
const repoInfo = window.sfMetadataContext.getSetting('repoInfo'); | ||
|
||
const images = useMemo(() => { | ||
return metadata.rows | ||
.map(record => { | ||
const recordType = getFileTypeFromRecord(record); | ||
if (recordType !== PREDEFINED_FILE_TYPE_OPTION_KEY.PICTURE) return null; | ||
const id = getRecordIdFromRecord(record); | ||
const fileName = getFileNameFromRecord(record); | ||
const name = getFileNameFromRecord(record); | ||
const parentDir = getParentDirFromRecord(record); | ||
const path = Utils.encodePath(Utils.joinPath(parentDir, fileName)); | ||
const src = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForGrid}${path}`; | ||
const path = Utils.encodePath(Utils.joinPath(parentDir, name)); | ||
const location = getImageLocationFromRecord(record); | ||
if (!location) return null; | ||
const { lng, lat } = location; | ||
if (!isValidPosition(lng, lat)) return null; | ||
const gcPosition = wgs84_to_gcj02(lng, lat); | ||
const bdPosition = gcj02_to_bd09(gcPosition.lng, gcPosition.lat); | ||
return { id, src, lng: bdPosition.lng, lat: bdPosition.lat }; | ||
}) | ||
.filter(Boolean); | ||
}, [repoID, metadata.rows]); | ||
|
||
const openCluster = useCallback((clusterIds) => { | ||
clusterRef.current = clusterIds; | ||
updateCurrentPath(`/${PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES}/${viewID}/${gettext('Location')}`); | ||
setShowCluster(true); | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [viewID, updateCurrentPath]); | ||
const repoEncrypted = repoInfo.encrypted; | ||
const cacheBuster = new Date().getTime(); | ||
const fileExt = name.substr(name.lastIndexOf('.') + 1).toLowerCase(); | ||
let thumbnail = ''; | ||
const isGIF = fileExt === 'gif'; | ||
if (repoEncrypted || isGIF) { | ||
thumbnail = `${siteRoot}repo/${repoID}/raw${path}?t=${cacheBuster}`; | ||
} else { | ||
thumbnail = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}`; | ||
} | ||
|
||
const closeCluster = useCallback(() => { | ||
clusterRef.current = []; | ||
updateCurrentPath(`/${PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES}/${viewID}`); | ||
setShowCluster(false); | ||
}, [viewID, updateCurrentPath]); | ||
return { | ||
id, | ||
name, | ||
src: `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForGrid}${path}`, | ||
url: `${siteRoot}lib/${repoID}/file${path}`, | ||
downloadURL: `${fileServerRoot}repos/${repoID}/files${path}?op=download`, | ||
thumbnail, | ||
parentDir, | ||
location: { lng: bdPosition.lng, lat: bdPosition.lat } | ||
}; | ||
}) | ||
.filter(Boolean); | ||
}, [repoID, repoInfo.encrypted, metadata]); | ||
|
||
useEffect(() => { | ||
updateCurrentPath(`/${PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES}/${viewID}`); | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, []); | ||
|
||
if (showCluster) { | ||
return (<ClusterPhotos photoIds={clusterRef.current} onClose={closeCluster} />); | ||
} | ||
|
||
return (<MapView images={images} onOpenCluster={openCluster} />); | ||
return (<MapView images={images} />); | ||
}; | ||
|
||
export default Map; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 26 additions & 76 deletions
102
frontend/src/metadata/views/map/map-view/overlay/custom-image-overlay.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,86 +1,36 @@ | ||
import { Utils } from '../../../../../utils/utils'; | ||
const OVERLAY_SIZE = 80; | ||
|
||
const customImageOverlay = (center, image, callback) => { | ||
class ImageOverlay extends window.BMapLib.TextIconOverlay { | ||
constructor(center, image, { callback } = {}) { | ||
super(center, '', { styles: [] }); | ||
this._center = center; | ||
this._URL = image.src; | ||
this._id = image.id; | ||
this._callback = callback; | ||
} | ||
const customImageOverlay = (props) => { | ||
const { isCluster, pointCount, reduces } = props; | ||
const src = isCluster ? reduces.src : props.src; | ||
|
||
initialize(map) { | ||
this._map = map; | ||
const div = document.createElement('div'); | ||
div.style.position = 'absolute'; | ||
div.style.zIndex = 2000; | ||
map.getPanes().markerPane.appendChild(div); | ||
this._div = div; | ||
const div = document.createElement('div'); | ||
div.style.position = 'absolute'; | ||
|
||
const imageElement = `<img src=${this._URL} />`; | ||
const htmlString = | ||
` | ||
<div class="custom-image-container"> | ||
${this._URL ? imageElement : '<div class="empty-custom-image-wrapper"></div>'} | ||
</div> | ||
`; | ||
const labelDocument = new DOMParser().parseFromString(htmlString, 'text/html'); | ||
const label = labelDocument.body.firstElementChild; | ||
this._div.append(label); | ||
const container = document.createElement('div'); | ||
container.className = 'custom-image-container'; | ||
|
||
const eventHandler = (event) => { | ||
event.preventDefault(); | ||
this._callback && this._callback(event, [{ _id: this._id }]); | ||
}; | ||
|
||
if (Utils.isDesktop()) { | ||
let clickTimeout; | ||
this._div.addEventListener('click', (event) => { | ||
if (clickTimeout) { | ||
clearTimeout(clickTimeout); | ||
clickTimeout = null; | ||
return; | ||
} | ||
clickTimeout = setTimeout(() => { | ||
eventHandler(event); | ||
clickTimeout = null; | ||
}, 300); | ||
}); | ||
this._div.addEventListener('dblclick', (e) => { | ||
e.preventDefault(); | ||
if (clickTimeout) { | ||
clearTimeout(clickTimeout); | ||
clickTimeout = null; | ||
} | ||
}); | ||
} else { | ||
this._div.addEventListener('touchend', eventHandler); | ||
} | ||
|
||
return div; | ||
} | ||
|
||
draw() { | ||
const position = this._map.pointToOverlayPixel(this._center); | ||
this._div.style.left = position.x - 40 + 'px'; // 40 is 1/2 container height | ||
this._div.style.top = position.y - 88 + 'px'; // 80 is container height and 8 is icon height | ||
} | ||
|
||
getImageUrl() { | ||
return image.src || ''; | ||
} | ||
|
||
getPosition() { | ||
return center; | ||
} | ||
if (isCluster && pointCount > 1) { | ||
const customImageNumber = document.createElement('span'); | ||
customImageNumber.className = 'custom-image-number'; | ||
customImageNumber.innerText = pointCount < 1000 ? pointCount : '1k+'; | ||
container.appendChild(customImageNumber); | ||
} | ||
|
||
getMap() { | ||
return this._map || null; | ||
} | ||
if (src) { | ||
const imageElement = document.createElement('img'); | ||
imageElement.src = src; | ||
imageElement.width = OVERLAY_SIZE; | ||
imageElement.height = OVERLAY_SIZE; | ||
container.appendChild(imageElement); | ||
} else { | ||
const emptyImageWrapper = document.createElement('div'); | ||
emptyImageWrapper.className = 'empty-custom-image-wrapper'; | ||
container.appendChild(emptyImageWrapper); | ||
} | ||
|
||
return new ImageOverlay(center, image, callback); | ||
div.appendChild(container); | ||
return div; | ||
}; | ||
|
||
export default customImageOverlay; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Oops, something went wrong.