2

写真の GPS-Exif 情報を読み取り、KML または CSV ファイルにタグ (緯度/経度など) を書き込むアプリを開発しています。ファイルが存在しない場合、特にcsvを作成することは問題ではありませんが、この場合、新しいKMLプレースマークを既存のKMLファイルに追加したいと考えています。

これまでのところ、ファイルが既に存在するかどうかを確認するメソッドを作成しました。そうでない場合 (if ステートメント)、新しいファイルを作成します。ファイルが存在する場合は、情報を追加する必要があります(else)。

public void createKMLFile(){


        String kmlstart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                        "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n";

        String kmlelement ="\t<Placemark>\n" +
                            "\t<name>Simple placemark</name>\n" +
                            "\t<description>"+name+"</description>\n" +
                            "\t<Point>\n" +
                            "\t\t<coordinates>"+latlon[1]+","+latlon[0]+","+z+ "</coordinates>\n" +
                            "\t</Point>\n" +
                            "\t</Placemark>\n";

        String kmlend = "</kml>";

        ArrayList<String> content = new ArrayList<String>();
        //content.add(0,kmlstart);
        //content.add(1,kmlelement);
        //content.add(2,kmlend);

        String kmltest;


        //Zum Einsetzen eines Substrings (weitere Placemark)
        //String test = "</kml>";
        //int index = kml.lastIndexOf(test);

        File test = new File(datapath+"/"+name+".kml");
        Writer fwriter;

        if(test.exists() == false){
            try {
                content.add(0,kmlstart);
                content.add(1,kmlelement);
                content.add(2,kmlend);
                kmltest = content.get(0) + content.get(1) + content.get(2);

                fwriter = new FileWriter(datapath+"/"+name+".kml");
                fwriter.write(kmltest);
                //fwriter.append("HalloHallo", index, kml.length());
                fwriter.flush();
                fwriter.close();
            }catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }   
        }
        else{
            kmltest = content.get(0) + content.get(1) + content.get(2);
            StringTokenizer tokenize = new StringTokenizer(kmltest, ">");
            ArrayList<String> append = new ArrayList<String>();
            while(tokenize.hasMoreTokens()){

            append.add(tokenize.nextToken());
            append.add(1, kmlelement);

            String rewrite = append.toString();
            try {
                fwriter = new FileWriter(datapath+"/"+name+".kml");
                fwriter.write(rewrite);
                fwriter.flush();
                fwriter.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


            }

        }



    }

LogCat でログを取得できませんが、既存のファイルを更新しようとするとアプリが動作しなくなります...何か提案はありますか? 前もって感謝します

編集:わかりました content.add(0, kml...) は try ブロックの外にある必要があります...しかし、それは主な問題ではないようです

4

2 に答える 2

4

それは今働いています、あなたの入力 rolfl に感謝します! 私のプログラムでは、はるかに快適なJDOMライブラリを使用してメソッドを実装しました. 出力はきれいな形式ではありませんが、kml ファイルは機能しています。

public void createKMLFile(){



        String kmlstart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                        "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n";

        String kmlelement ="\t<Placemark>\n" +
                            "\t<name>Simple placemark</name>\n" +
                            "\t<description>"+name+"</description>\n" +
                            "\t<Point>\n" +
                            "\t\t<coordinates>"+latlon[1]+","+latlon[0]+","+z+ "</coordinates>\n" +
                            "\t</Point>\n" +
                            "\t</Placemark>\n";

        String kmlend = "</kml>";

        ArrayList<String> content = new ArrayList<String>();
        content.add(0,kmlstart);
        content.add(1,kmlelement);
        content.add(2,kmlend);

        String kmltest = content.get(0) + content.get(1) + content.get(2);


        File testexists = new File(datapath+"/"+name+".kml");
        Writer fwriter;

        if(!testexists.exists()){
            try {

                fwriter = new FileWriter(datapath+"/"+name+".kml");
                fwriter.write(kmltest);
                fwriter.flush();
                fwriter.close();
            }catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }   
        }

        else{

            //schleifenvariable
            String filecontent ="";

            ArrayList<String> newoutput = new ArrayList<String>();;

            try {
                BufferedReader in = new BufferedReader(new FileReader(testexists));
                while((filecontent = in.readLine()) !=null)

                    newoutput.add(filecontent);

            } catch (FileNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            newoutput.add(2,kmlelement);

            String rewrite ="";
            for(String s : newoutput){
                rewrite += s;
            }

            try {
                fwriter = new FileWriter(datapath+"/"+name+".kml");
                fwriter.write(rewrite);
                fwriter.flush();
                fwriter.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

    }
于 2013-09-11T17:01:59.537 に答える
3

XML ファイルを変更するときは、ある種のライブラリを使用して行うのが最善です。私は、この種の操作をできる限り簡単にするために設計されたJDOM と呼ばれる XML 操作ライブラリーを維持しています。その他のオプションとして、DOM ライブラリ(既に Java ランタイムに組み込まれているため、プログラムへの統合がはるかに簡単になります)と SAX (この場合は、高速かもしれませんが、お勧めしません) を使用する方法があります。 )。XOM、dom4j など、他の外部ライブラリ (JDOM など) も役立ちます

JDOM では、コードは次のようになります。

    Document doc = null;
    Namespace kmlns = new Namespace("http://www.opengis.net/kml/2.2");
    Element position = new Element("Position", kmlns);
    position.addContent(new Element("name", kmlns).setText(positionName));
    position.addContent(new Element("desc", kmlns).setText(description));
    position.addContent(.....   all the XML content needed for the Position ....);

    // create the XML Document in memory if the file does not exist
    // otherwise read the file from the disk
    if(!test.exists()){
            doc = new Document();
            Element root = new Element("kml", kmlns);
    } else {
            SAXBuilder sb = new SAXBuilder();
            doc = sb.build(test);
    }

    Element root = doc.getRootElement();
    // modify the XML as you need
    // add Position Element
    root.addContent(position);

    try {
        fwriter = new FileWriter(datapath+"/"+name+".kml");
        XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
        xout.output(doc, writer);
        fwriter.flush();
        fwriter.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

編集:実際のコードの何が問題なのかを尋ねます....問題の原因となっていることがいくつかありますが、実際のエラーや、プログラムが「動作を停止する」方法を示すその他の兆候は表示されません。

  1. コードに重大な例外をスローするバグがあります:kmltest = content.get(0) + content.get(1) + content.get(2);内容の ArrayList が空であるため、IndexOutOfBoundsException をスローする必要があります (ArrayList に値を追加する行はコメントアウトされています....) - しかし、そうでないと仮定しましょう....
  2. 変更しているファイルを読んだことがないのに、どうやって変更できるのでしょうか?
  3. StringTokenizer 区切り記号は です">"。これは、XML を解析するための良い方法ではありません。
  4. evert '>' デリミターで String トークナイザーをループしますが、トークンを出力に追加し直すことはありません (つまり、出力が多くの '>' 文字をミリングしています)。
  5. 重要な文字だけでなく、ドキュメント内のすべての「>」文字の場所に kmlelement の位置コンテンツを追加します。
  6. FileWriter ロジックは、ループの ** 外** にある必要があります。変更するトークンごとにファイルを変更する必要はありません。
于 2013-09-10T17:46:43.843 に答える