Sfoglia il codice sorgente

EarthService 从 content-service 迁移到 file-service

reghao 3 mesi fa
parent
commit
bea116d014

+ 0 - 6
content/content-service/pom.xml

@@ -158,12 +158,6 @@
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>org.dom4j</groupId>
-            <artifactId>dom4j</artifactId>
-            <version>2.1.1</version>
-        </dependency>
-
         <dependency>
             <groupId>org.jsoup</groupId>
             <artifactId>jsoup</artifactId>

+ 16 - 0
file/file-service/pom.xml

@@ -124,6 +124,22 @@
             <version>2.14.0</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.drewnoakes</groupId>
+            <artifactId>metadata-extractor</artifactId>
+            <version>2.18.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-imaging</artifactId>
+            <version>1.0-alpha3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.dom4j</groupId>
+            <artifactId>dom4j</artifactId>
+            <version>2.1.1</version>
+        </dependency>
+
         <dependency>
             <groupId>org.springdoc</groupId>
             <artifactId>springdoc-openapi-ui</artifactId>

+ 19 - 10
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/EarthService.java → file/file-service/src/main/java/cn/reghao/tnb/file/app/service/EarthService.java

@@ -1,7 +1,7 @@
-package cn.reghao.tnb.content.app.geo.service;
+package cn.reghao.tnb.file.app.service;
 
 import cn.reghao.tnb.common.web.ServletUtil;
-import cn.reghao.tnb.content.app.geo.model.vo.MapMarker;
+import cn.reghao.tnb.content.api.dto.CamPhoto;
 import org.dom4j.Document;
 import org.dom4j.Element;
 import org.dom4j.io.OutputFormat;
@@ -24,8 +24,12 @@ import java.util.List;
  */
 @Service
 public class EarthService {
-    public void getEarthKml(List<MapMarker> list) throws Exception {
-        String template = "";
+    public void getEarthKml(String kmlFile, List<CamPhoto> list) throws Exception {
+        String template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+                "<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n" +
+                "<Document>\n" +
+                "</Document>\n" +
+                "</kml>";
         ByteArrayInputStream inputStream = new ByteArrayInputStream(template.getBytes(StandardCharsets.UTF_8));
         SAXReader reader = new SAXReader();
         Document document = reader.read(inputStream);
@@ -34,7 +38,7 @@ public class EarthService {
         Element root = iterator.next();
         root.addElement("name").setText("exports");
         Element folder = addFolder(root, "dir1");
-        for (MapMarker mapMarker : list) {
+        for (CamPhoto mapMarker : list) {
             addPlaceMark(folder, mapMarker);
         }
 
@@ -47,7 +51,7 @@ public class EarthService {
             addPlaceMark(folder2, mapMarker);
         }*/
 
-        File out = new File("/home/reghao/Downloads/places2.kml");
+        File out = new File(kmlFile);
         OutputStream outputStream = new FileOutputStream(out);
         //ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         OutputFormat format = OutputFormat.createPrettyPrint();
@@ -70,10 +74,15 @@ public class EarthService {
         return folder;
     }
 
-    private void addPlaceMark(Element element, MapMarker mapMarker) {
-        String name = mapMarker.getTitle();
-        String lat = mapMarker.getPosition().getLat().toString();
-        String lng = mapMarker.getPosition().getLng().toString();
+    private void addPlaceMark(Element element, CamPhoto camPhoto) {
+        String photoUrl = camPhoto.getPhotoUrl();
+        String[] arr = photoUrl.split("/");
+        String filename = arr[arr.length-1].replace("IMG_", "").replace(".jpg", "");
+
+        String name = filename;
+        //String name = camPhoto.getPhotoUrl();
+        String lat = camPhoto.getLatitude().toString();
+        String lng = camPhoto.getLongitude().toString();
 
         Element placeMark = element.addElement("Placemark");
         placeMark.addElement("name").setText(name);

+ 125 - 0
file/file-service/src/main/java/cn/reghao/tnb/file/app/util/PhotoExif.java

@@ -0,0 +1,125 @@
+package cn.reghao.tnb.file.app.util;
+
+import cn.reghao.tnb.content.api.dto.CamPhoto;
+import com.drew.imaging.ImageMetadataReader;
+import com.drew.imaging.ImageProcessingException;
+import com.drew.lang.GeoLocation;
+import com.drew.metadata.Directory;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.Tag;
+import com.drew.metadata.exif.ExifIFD0Directory;
+import com.drew.metadata.exif.GpsDirectory;
+import org.apache.commons.imaging.ImageReadException;
+import org.apache.commons.imaging.ImageWriteException;
+import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;
+import org.apache.commons.imaging.formats.jpeg.xmp.JpegXmpRewriter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * @author reghao
+ * @date 2023-09-06 14:25:18
+ */
+public class PhotoExif {
+    public static void getExifInfo(File file) throws ImageProcessingException, IOException {
+        Metadata metadata = ImageMetadataReader.readMetadata(file);
+
+        for (Directory directory : metadata.getDirectories()) {
+            for (Tag tag : directory.getTags()) {
+                String dirname = tag.getDirectoryName();
+                String name = tag.getTagName();
+                String description = tag.getDescription();
+                System.out.println(dirname + ":" + name + " -> " + description);
+            }
+        }
+
+        Collection<GpsDirectory> gpsDirectories = metadata.getDirectoriesOfType(GpsDirectory.class);
+        for(GpsDirectory gps : gpsDirectories) {
+            GeoLocation geoLocation = gps.getGeoLocation();
+            if (geoLocation != null) {
+                double longitude = geoLocation.getLongitude();
+                double latitude = geoLocation.getLatitude();
+                System.out.printf("%s,%s\n", latitude, longitude);
+            }
+        }
+    }
+
+    public static String removeExif(File srcFile) throws IOException, ImageWriteException, ImageReadException {
+        String parentPath = srcFile.getParent();
+        String srcName = srcFile.getName();
+        int idx = srcName.lastIndexOf(".");
+        if (idx == -1) {
+            throw new IOException("photo file not end with suffix");
+        }
+
+        String destName = String.format("%s_noexif%s", srcName.substring(0, idx), srcName.substring(idx));
+        String destPath = String.format("%s%s%s", parentPath, File.separator, destName);
+        FileOutputStream fos = new FileOutputStream(destPath);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ExifRewriter exifRewriter = new ExifRewriter();
+        exifRewriter.removeExifMetadata(srcFile, baos);
+
+        JpegXmpRewriter jpegXmpRewriter = new JpegXmpRewriter();
+        jpegXmpRewriter.removeXmpXml(baos.toByteArray(), fos);
+        return destPath;
+    }
+
+    public static CamPhoto getCamPhoto(String filePath) {
+        File file = new File(filePath);
+        if (!file.exists()) {
+            return null;
+        }
+
+        CamPhoto camPhoto = new CamPhoto(filePath);
+        try {
+            Metadata metadata = ImageMetadataReader.readMetadata(file);
+            Collection<GpsDirectory> gpsDirectories = metadata.getDirectoriesOfType(GpsDirectory.class);
+            for(GpsDirectory gps : gpsDirectories) {
+                GeoLocation geoLocation = gps.getGeoLocation();
+                if (geoLocation != null) {
+                    double longitude = geoLocation.getLongitude();
+                    double latitude = geoLocation.getLatitude();
+
+                    camPhoto.setLongitude(longitude);
+                    camPhoto.setLatitude(latitude);
+                }
+            }
+
+            Collection<ExifIFD0Directory> exifDirectories = metadata.getDirectoriesOfType(ExifIFD0Directory.class);
+            for (ExifIFD0Directory exif : exifDirectories) {
+                for (Tag tag : exif.getTags()) {
+                    String tagName = tag.getTagName();
+                    String desc = tag.getDescription();
+                    switch (tagName) {
+                        case "Make":
+                            camPhoto.setManufacturer(desc);
+                            break;
+                        case "Model":
+                            camPhoto.setModel(desc);
+                            break;
+                        case "Software":
+                            camPhoto.setSoftware(desc);
+                            break;
+                        case "Date/Time":
+                            String[] arr = desc.split(" ");
+                            if (arr.length == 2) {
+                                String date = arr[0].replace(":", "-");
+                                String dateTime = String.format("%s %s", date, arr[1]);
+                                camPhoto.setShotAt(dateTime);
+                            }
+                            break;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return camPhoto;
+    }
+}

+ 53 - 1
file/file-service/src/test/java/FileTest.java

@@ -1,10 +1,21 @@
+import cn.reghao.tnb.content.api.dto.CamPhoto;
 import cn.reghao.tnb.file.app.FileApplication;
+import cn.reghao.tnb.file.app.service.EarthService;
+import cn.reghao.tnb.file.app.util.PhotoExif;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.ActiveProfiles;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -15,7 +26,48 @@ import java.util.List;
 @ActiveProfiles("dev")
 @SpringBootTest(classes = FileApplication.class)
 public class FileTest {
+    void walkDir(Path path) throws IOException {
+        Files.walkFileTree(path, new FileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+                return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                File file1 = file.toFile();
+                process(file1);
+                return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
+                return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+                return FileVisitResult.CONTINUE;
+            }
+        });
+    }
+
+    List<CamPhoto> camPhotoList = new ArrayList<>();
+    private void process(File file) {
+        CamPhoto camPhoto = PhotoExif.getCamPhoto(file.getAbsolutePath());
+        if (camPhoto != null && camPhoto.getLatitude() != null) {
+            camPhotoList.add(camPhoto);
+        }
+    }
+
+    String baseDir = "/home/reghao/data/vdisk/320g/photo/";
+    String kmlFile = "/home/reghao/Downloads/my_places.kml";
+    @Autowired
+    EarthService earthService;
     @Test
-    public void test() {
+    public void photoTest() throws Exception {
+        walkDir(Path.of(baseDir));
+        earthService.getEarthKml(kmlFile, camPhotoList);
+        System.out.println();
     }
 }